/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2012 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:pk-task * @short_description: An abstract package task GObject, dealing with unsigned * transactions, GPG keys and EULA requests. */ #include "config.h" #include #include #include #include #include static void pk_task_finalize (GObject *object); #define PK_TASK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_TASK, PkTaskPrivate)) #define PK_TASK_TRANSACTION_CANCELLED_RETRY_TIMEOUT 2000 /* ms */ /** * PkTaskPrivate: * * Private #PkTask data **/ struct _PkTaskPrivate { GHashTable *gtasks; /* uint, GTask* */ gboolean simulate; gboolean only_download; gboolean only_trusted; gboolean allow_reinstall; gboolean allow_downgrade; }; enum { PROP_0, PROP_SIMULATE, PROP_ONLY_PREPARE, PROP_ONLY_TRUSTED, PROP_ALLOW_REINSTALL, PROP_ALLOW_DOWNGRADE, PROP_LAST }; /** * PkTaskState: * * For use in the async methods **/ typedef struct { guint request; PkRoleEnum role; PkExitEnum exit_enum; gboolean simulate; gboolean only_download; gboolean allow_reinstall; gboolean allow_downgrade; gboolean transaction_flags; gchar **package_ids; gboolean allow_deps; gboolean autoremove; gchar **files; PkResults *results; PkProgressCallback progress_callback; gpointer progress_user_data; gboolean enabled; gboolean force; gboolean recursive; gchar *directory; gchar *distro_id; gchar **packages; gchar *repo_id; gchar *transaction_id; gchar **values; PkBitfield filters; PkUpgradeKindEnum upgrade_kind; guint retry_id; } PkTaskState; G_DEFINE_TYPE (PkTask, pk_task, PK_TYPE_CLIENT) static void pk_task_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data); /* * pk_task_generate_request_id: **/ static guint pk_task_generate_request_id (void) { static guint id = 0; return ++id; } /* * pk_task_find_by_request: **/ static inline GTask * pk_task_find_by_request (PkTask *task, guint request) { g_return_val_if_fail (PK_IS_TASK (task), NULL); g_return_val_if_fail (request != 0, NULL); return g_hash_table_lookup (task->priv->gtasks, GUINT_TO_POINTER (request)); } /* * pk_task_generic_state_finish: **/ static void pk_task_state_free (gpointer task_state) { PkTaskState *state = task_state; if (state->retry_id != 0) g_source_remove (state->retry_id); g_free (state->directory); g_free (state->distro_id); g_free (state->repo_id); g_free (state->transaction_id); g_strfreev (state->files); g_strfreev (state->package_ids); g_strfreev (state->packages); g_strfreev (state->values); g_slice_free (PkTaskState, state); } /* * pk_task_do_async_action: **/ static void pk_task_do_async_action (GTask *gtask) { PkTask *task = g_task_get_source_object (gtask); PkTaskState *state = g_task_get_task_data (gtask); GCancellable *cancellable = g_task_get_cancellable (gtask); PkBitfield transaction_flags; /* so the callback knows if we are serious or not */ state->simulate = FALSE; /* only prepare the transaction */ transaction_flags = state->transaction_flags; if (task->priv->only_download) { pk_bitfield_add (transaction_flags, PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD); } if (task->priv->allow_reinstall) { pk_bitfield_add (transaction_flags, PK_TRANSACTION_FLAG_ENUM_ALLOW_REINSTALL); } if (task->priv->allow_downgrade) { pk_bitfield_add (transaction_flags, PK_TRANSACTION_FLAG_ENUM_ALLOW_DOWNGRADE); } /* do the correct action */ if (state->role == PK_ROLE_ENUM_INSTALL_PACKAGES) { pk_client_install_packages_async (PK_CLIENT(task), transaction_flags, state->package_ids, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_UPDATE_PACKAGES) { pk_client_update_packages_async (PK_CLIENT(task), transaction_flags, state->package_ids, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_REMOVE_PACKAGES) { pk_client_remove_packages_async (PK_CLIENT(task), transaction_flags, state->package_ids, state->allow_deps, state->autoremove, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_INSTALL_FILES) { pk_client_install_files_async (PK_CLIENT(task), transaction_flags, state->files, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_RESOLVE) { pk_client_resolve_async (PK_CLIENT(task), state->filters, state->packages, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_SEARCH_NAME) { pk_client_search_names_async (PK_CLIENT(task), state->filters, state->values, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_SEARCH_DETAILS) { pk_client_search_details_async (PK_CLIENT(task), state->filters, state->values, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_SEARCH_GROUP) { pk_client_search_groups_async (PK_CLIENT(task), state->filters, state->values, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_SEARCH_FILE) { pk_client_search_files_async (PK_CLIENT(task), state->filters, state->values, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_GET_DETAILS) { pk_client_get_details_async (PK_CLIENT(task), state->package_ids, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) { pk_client_get_update_detail_async (PK_CLIENT(task), state->package_ids, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_DOWNLOAD_PACKAGES) { pk_client_download_packages_async (PK_CLIENT(task), state->package_ids, state->directory, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_GET_UPDATES) { pk_client_get_updates_async (PK_CLIENT(task), state->filters, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_DEPENDS_ON) { pk_client_depends_on_async (PK_CLIENT(task), state->filters, state->package_ids, state->recursive, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_GET_PACKAGES) { pk_client_get_packages_async (PK_CLIENT(task), state->filters, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_REQUIRED_BY) { pk_client_required_by_async (PK_CLIENT(task), state->filters, state->package_ids, state->recursive, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_WHAT_PROVIDES) { pk_client_what_provides_async (PK_CLIENT(task), state->filters, state->values, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_GET_FILES) { pk_client_get_files_async (PK_CLIENT(task), state->package_ids, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_GET_CATEGORIES) { pk_client_get_categories_async (PK_CLIENT(task), cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_REFRESH_CACHE) { pk_client_refresh_cache_async (PK_CLIENT(task), state->force, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_GET_REPO_LIST) { pk_client_get_repo_list_async (PK_CLIENT(task), state->filters, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_REPO_ENABLE) { pk_client_repo_enable_async (PK_CLIENT(task), state->repo_id, state->enabled, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_UPGRADE_SYSTEM) { pk_client_upgrade_system_async (PK_CLIENT(task), transaction_flags, state->distro_id, state->upgrade_kind, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_REPAIR_SYSTEM) { pk_client_repair_system_async (PK_CLIENT(task), transaction_flags, cancellable, state->progress_callback, state->progress_user_data, pk_task_ready_cb, g_steal_pointer (>ask)); } else { g_assert_not_reached (); } } /* * pk_task_package_filter_cb: **/ static gboolean pk_task_package_filter_cb (PkPackage *package, gpointer user_data) { PkInfoEnum info; info = pk_package_get_info (package); if (info == PK_INFO_ENUM_CLEANUP || info == PK_INFO_ENUM_UNTRUSTED || info == PK_INFO_ENUM_FINISHED) return FALSE; if (g_strcmp0 (pk_package_get_data (package), "local") == 0) return FALSE; return TRUE; } static void pk_task_do_async_simulate_action (GTask *gtask); /* * pk_task_simulate_ready_cb: **/ static void pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GTask) gtask = G_TASK (user_data); g_autoptr(GError) error = NULL; g_autoptr(PkPackageSack) sack = NULL; g_autoptr(PkPackageSack) untrusted_sack = NULL; PkTask *task = g_task_get_source_object (gtask); PkTaskState *state = g_task_get_task_data (gtask); /* old results no longer valid */ g_clear_object (&state->results); /* get the results */ state->results = pk_client_generic_finish (PK_CLIENT(source_object), res, &error); if (state->results == NULL) { /* handle case where this is not implemented */ if (error->code == PK_CLIENT_ERROR_NOT_SUPPORTED) { pk_task_do_async_action (g_steal_pointer (>ask)); return; } /* just abort */ g_task_return_error (gtask, g_steal_pointer (&error)); return; } /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); if (state->exit_enum == PK_EXIT_ENUM_NEED_UNTRUSTED) { g_debug ("retrying with !only-trusted"); pk_bitfield_remove (state->transaction_flags, PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); /* retry this */ pk_task_do_async_simulate_action (g_steal_pointer (>ask)); return; } if (state->exit_enum != PK_EXIT_ENUM_SUCCESS) { /* we 'fail' with success so the application gets a * chance to process the PackageKit-specific * ErrorCode enumerated value and detail. */ g_task_return_pointer (gtask, g_steal_pointer (&state->results), g_object_unref); return; } /* get data */ sack = pk_results_get_package_sack (state->results); /* if we did a simulate and we got a message that a package was untrusted, * there's no point trying to do the action with only-trusted */ untrusted_sack = pk_package_sack_filter_by_info (sack, PK_INFO_ENUM_UNTRUSTED); if (pk_package_sack_get_size (untrusted_sack) > 0) { g_debug ("we got an untrusted message, so skipping only-trusted"); pk_bitfield_remove (state->transaction_flags, PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); } /* remove all the packages we want to ignore */ pk_package_sack_remove_by_filter (sack, pk_task_package_filter_cb, NULL); /* no results from simulate */ if (pk_package_sack_get_size (sack) == 0) { pk_task_do_async_action (g_steal_pointer (>ask)); return; } /* sort the list, as clients will mostly want this */ pk_package_sack_sort (sack, PK_PACKAGE_SACK_SORT_TYPE_INFO); /* run the callback */ PK_TASK_GET_CLASS (task)->simulate_question (task, state->request, state->results); } /* * pk_task_do_async_simulate_action: **/ static void pk_task_do_async_simulate_action (GTask *gtask) { PkTask *task = g_task_get_source_object (gtask); PkTaskState *state = g_task_get_task_data (gtask); GCancellable *cancellable = g_task_get_cancellable (gtask); PkBitfield transaction_flags = state->transaction_flags; /* so the callback knows if we are serious or not */ pk_bitfield_add (transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE); state->simulate = TRUE; /* do the correct action */ if (state->role == PK_ROLE_ENUM_INSTALL_PACKAGES) { /* simulate install async */ g_debug ("doing install"); pk_client_install_packages_async (PK_CLIENT(task), transaction_flags, state->package_ids, cancellable, state->progress_callback, state->progress_user_data, pk_task_simulate_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_UPDATE_PACKAGES) { /* simulate update async */ g_debug ("doing update"); pk_client_update_packages_async (PK_CLIENT(task), transaction_flags, state->package_ids, cancellable, state->progress_callback, state->progress_user_data, pk_task_simulate_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_REMOVE_PACKAGES) { /* simulate remove async */ g_debug ("doing remove"); pk_client_remove_packages_async (PK_CLIENT(task), transaction_flags, state->package_ids, state->allow_deps, state->autoremove, cancellable, state->progress_callback, state->progress_user_data, pk_task_simulate_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_INSTALL_FILES) { /* simulate install async */ g_debug ("doing install files"); pk_client_install_files_async (PK_CLIENT(task), transaction_flags, state->files, cancellable, state->progress_callback, state->progress_user_data, pk_task_simulate_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_UPGRADE_SYSTEM) { /* simulate upgrade system async */ g_debug ("doing upgrade system"); pk_client_upgrade_system_async (PK_CLIENT(task), transaction_flags, state->distro_id, state->upgrade_kind, cancellable, state->progress_callback, state->progress_user_data, pk_task_simulate_ready_cb, g_steal_pointer (>ask)); } else if (state->role == PK_ROLE_ENUM_REPAIR_SYSTEM) { /* simulate repair system async */ g_debug ("doing repair system"); pk_client_repair_system_async (PK_CLIENT(task), transaction_flags, cancellable, state->progress_callback, state->progress_user_data, pk_task_simulate_ready_cb, g_steal_pointer (>ask)); } else { g_assert_not_reached (); } } /* * pk_task_install_signatures_ready_cb: **/ static void pk_task_install_signatures_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GTask) gtask = G_TASK (user_data); PkTask *task = PK_TASK (source_object); PkTaskState *state = g_task_get_task_data (gtask); g_autoptr(GError) error = NULL; /* old results no longer valid */ g_clear_object (&state->results); /* get the results */ state->results = pk_client_generic_finish (PK_CLIENT(task), res, &error); if (state->results == NULL) { g_task_return_error (gtask, g_steal_pointer (&error)); return; } /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); /* need untrusted */ if (state->exit_enum != PK_EXIT_ENUM_SUCCESS) { g_autoptr(PkError) error_code = NULL; error_code = pk_results_get_error_code (state->results); /* TODO: convert the PkErrorEnum to a PK_CLIENT_ERROR_* enum */ g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "failed to install signature: %s", pk_error_get_details (error_code)); return; } /* now try the action again */ pk_task_do_async_action (g_steal_pointer (>ask)); } /* * pk_task_install_signatures: **/ static void pk_task_install_signatures (GTask *given_gtask) { g_autoptr(GTask) gtask = given_gtask; PkTask *task = g_task_get_source_object (gtask); PkTaskState *state = g_task_get_task_data (gtask); PkRepoSignatureRequired *item; PkSigTypeEnum type; g_autoptr(GError) error = NULL; g_autofree gchar *key_id = NULL; g_autofree gchar *package_id = NULL; g_autoptr(GPtrArray) array = NULL; GCancellable *cancellable; /* get results */ array = pk_results_get_repo_signature_required_array (state->results); if (array == NULL || array->len == 0) { g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "no signatures to install"); return; } /* did we get more than result? */ if (array->len > 1) { /* TODO: support more than one signature */ g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "more than one signature to install"); return; } /* get first item of data */ item = g_ptr_array_index (array, 0); g_object_get (item, "type", &type, "key-id", &key_id, "package-id", &package_id, NULL); /* do new async method */ cancellable = g_task_get_cancellable (gtask); pk_client_install_signature_async (PK_CLIENT(task), type, key_id, package_id, cancellable, state->progress_callback, state->progress_user_data, pk_task_install_signatures_ready_cb, g_steal_pointer (>ask)); } /* * pk_task_accept_eulas_ready_cb: **/ static void pk_task_accept_eulas_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GTask) gtask = G_TASK (user_data); PkTask *task = PK_TASK (source_object); PkTaskState *state = g_task_get_task_data (gtask); g_autoptr(GError) error = NULL; /* old results no longer valid */ g_clear_object (&state->results); /* get the results */ state->results = pk_client_generic_finish (PK_CLIENT(task), res, &error); if (state->results == NULL) { g_task_return_error (gtask, g_steal_pointer (&error)); return; } /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); /* need untrusted */ if (state->exit_enum != PK_EXIT_ENUM_SUCCESS) { g_autoptr(PkError) error_code = NULL; error_code = pk_results_get_error_code (state->results); /* TODO: convert the PkErrorEnum to a PK_CLIENT_ERROR_* enum */ g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "failed to accept eula: %s", pk_error_get_details (error_code)); return; } /* now try the action again */ pk_task_do_async_action (g_steal_pointer (>ask)); } /* * pk_task_accept_eulas: **/ static void pk_task_accept_eulas (GTask *given_gtask) { g_autoptr(GTask) gtask = given_gtask; PkTask *task = g_task_get_source_object (gtask); PkTaskState *state = g_task_get_task_data (gtask); PkEulaRequired *item; g_autoptr(GError) error = NULL; const gchar *eula_id; g_autoptr(GPtrArray) array = NULL; GCancellable *cancellable; /* get results */ array = pk_results_get_eula_required_array (state->results); if (array == NULL || array->len == 0) { g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "no eulas to accept"); return; } /* did we get more than result? */ if (array->len > 1) { /* TODO: support more than one eula */ g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "more than one eula to accept"); return; } /* get first item of data */ item = g_ptr_array_index (array, 0); eula_id = pk_eula_required_get_eula_id (item); /* do new async method */ cancellable = g_task_get_cancellable (gtask); pk_client_accept_eula_async (PK_CLIENT(task), eula_id, cancellable, state->progress_callback, state->progress_user_data, pk_task_accept_eulas_ready_cb, g_steal_pointer (>ask)); } /* * pk_task_repair_ready_cb: **/ static void pk_task_repair_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GTask) gtask = G_TASK (user_data); PkTaskState *state = g_task_get_task_data (gtask); PkTask *task = PK_TASK (source_object); g_autoptr(GError) error = NULL; /* old results no longer valid */ g_clear_object (&state->results); /* get the results */ state->results = pk_client_generic_finish (PK_CLIENT(task), res, &error); if (state->results == NULL) { g_task_return_error (gtask, g_steal_pointer (&error)); return; } /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); /* need untrusted */ if (state->exit_enum != PK_EXIT_ENUM_SUCCESS) { g_autoptr(PkError) error_code = NULL; error_code = pk_results_get_error_code (state->results); /* TODO: convert the PkErrorEnum to a PK_CLIENT_ERROR_* enum */ g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "failed to repair: %s", pk_error_get_details (error_code)); return; } /* now try the action again */ pk_task_do_async_action (g_steal_pointer (>ask)); } /* * pk_task_user_accepted_idle_cb: **/ static gboolean pk_task_user_accepted_idle_cb (gpointer user_data) { g_autoptr(GTask) gtask = user_data; PkTaskState *state = g_task_get_task_data (gtask); /* this needs another step in the dance */ if (state->exit_enum == PK_EXIT_ENUM_KEY_REQUIRED) { g_debug ("need to do install-sig"); pk_task_install_signatures (g_steal_pointer (>ask)); return FALSE; } /* this needs another step in the dance */ if (state->exit_enum == PK_EXIT_ENUM_EULA_REQUIRED) { g_debug ("need to do accept-eula"); pk_task_accept_eulas (g_steal_pointer (>ask)); return FALSE; } /* this needs another step in the dance */ if (state->exit_enum == PK_EXIT_ENUM_REPAIR_REQUIRED) { GCancellable *cancellable = g_task_get_cancellable (gtask); PkTask *task = g_task_get_source_object (gtask); g_debug ("need to do repair"); pk_client_repair_system_async (PK_CLIENT(task), pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_NONE), cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_repair_ready_cb, g_steal_pointer (>ask)); return FALSE; } /* doing task */ g_debug ("continuing with request %i", state->request); pk_task_do_async_action (g_steal_pointer (>ask)); return FALSE; } /** * pk_task_user_accepted: * @task: a valid #PkTask instance * @request: request ID for EULA. * * Mark a EULA as accepted by the user. * * Return value: %TRUE if @request is valid. * * Since: 0.5.2 **/ gboolean pk_task_user_accepted (PkTask *task, guint request) { GTask *gtask; GSource *idle_source; /* get the not-yet-completed request */ gtask = pk_task_find_by_request (task, request); if (gtask == NULL) { g_warning ("request %i not found", request); return FALSE; } idle_source = g_idle_source_new (); g_source_set_callback (idle_source, G_SOURCE_FUNC (pk_task_user_accepted_idle_cb), g_object_ref (gtask), g_object_unref); g_source_set_name (idle_source, "[PkTask] user-accept"); g_source_attach (idle_source, g_main_context_get_thread_default ()); return TRUE; } /* * pk_task_user_declined_idle_cb: **/ static gboolean pk_task_user_declined_idle_cb (gpointer user_data) { g_autoptr(GTask) gtask = user_data; PkTaskState *state; state = g_task_get_task_data (gtask); /* the introduction is finished */ if (state->simulate) { g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_DECLINED_SIMULATION, "user declined simulation"); return FALSE; } /* doing task */ g_debug ("declined request %i", state->request); g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_DECLINED_INTERACTION, "user declined interaction"); return FALSE; } /** * pk_task_user_declined: * @task: a valid #PkTask instance * @request: request ID for EULA. * * Mark a EULA as declined by the user. * * Return value: %TRUE if @request is valid. * * Since: 0.5.2 **/ gboolean pk_task_user_declined (PkTask *task, guint request) { GTask *gtask; GSource *idle_source; /* get the not-yet-completed request */ gtask = pk_task_find_by_request (task, request); if (gtask == NULL) { g_warning ("request %i not found", request); return FALSE; } idle_source = g_idle_source_new (); g_source_set_callback (idle_source, G_SOURCE_FUNC (pk_task_user_declined_idle_cb), g_object_ref (gtask), g_object_unref); g_source_set_name (idle_source, "[PkTask] user-accept"); g_source_attach (idle_source, g_main_context_get_thread_default ()); return TRUE; } /* * pk_task_retry_cancelled_transaction_cb: **/ static gboolean pk_task_retry_cancelled_transaction_cb (gpointer user_data) { g_autoptr(GTask) gtask = G_TASK (user_data); PkTaskState *state = g_task_get_task_data (gtask); pk_task_do_async_action (g_steal_pointer (>ask)); state->retry_id = 0; return G_SOURCE_REMOVE; } /* * pk_task_ready_cb: **/ static void pk_task_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GTask) gtask = G_TASK (user_data); PkTask *task = PK_TASK (source_object); PkTaskClass *klass = PK_TASK_GET_CLASS (task); PkTaskState *state = g_task_get_task_data (gtask); gboolean interactive; g_autoptr(GError) error = NULL; /* old results no longer valid */ g_clear_object (&state->results); /* get the results */ state->results = pk_client_generic_finish (PK_CLIENT(task), res, &error); if (state->results == NULL) { g_task_return_error (gtask, g_steal_pointer (&error)); return; } /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); /* can we ask the user questions? */ interactive = pk_client_get_interactive (PK_CLIENT (task)); /* need untrusted */ if (state->exit_enum == PK_EXIT_ENUM_NEED_UNTRUSTED) { pk_bitfield_remove (state->transaction_flags, PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); /* running non-interactive */ if (!interactive) { g_debug ("working non-interactive, so calling accept"); pk_task_user_accepted (task, state->request); return; } /* no support */ if (klass->untrusted_question == NULL) { g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do untrusted question as no klass support"); return; } /* run the callback */ klass->untrusted_question (task, state->request, state->results); return; } /* need key */ if (state->exit_enum == PK_EXIT_ENUM_KEY_REQUIRED) { /* running non-interactive */ if (!interactive) { g_debug ("working non-interactive, so calling accept"); pk_task_user_accepted (task, state->request); return; } /* no support */ if (klass->key_question == NULL) { g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do key question as no klass support"); return; } /* run the callback */ klass->key_question (task, state->request, state->results); return; } /* need repair */ if (state->exit_enum == PK_EXIT_ENUM_REPAIR_REQUIRED) { /* running non-interactive */ if (!interactive) { g_debug ("working non-interactive, so calling accept"); pk_task_user_accepted (task, state->request); return; } /* no support */ if (klass->repair_question == NULL) { g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do repair question as no klass support"); return; } /* run the callback */ klass->repair_question (task, state->request, state->results); return; } /* need EULA */ if (state->exit_enum == PK_EXIT_ENUM_EULA_REQUIRED) { /* running non-interactive */ if (!interactive) { g_debug ("working non-interactive, so calling accept"); pk_task_user_accepted (task, state->request); return; } /* no support */ if (klass->eula_question == NULL) { g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do eula question as no klass support"); return; } /* run the callback */ klass->eula_question (task, state->request, state->results); return; } /* need media change */ if (state->exit_enum == PK_EXIT_ENUM_MEDIA_CHANGE_REQUIRED) { /* running non-interactive */ if (!interactive) { g_debug ("working non-interactive, so calling accept"); pk_task_user_accepted (task, state->request); g_task_return_pointer (gtask, g_steal_pointer (&state->results), g_object_unref); return; } /* no support */ if (klass->media_change_question == NULL) { g_task_return_new_error (gtask, PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do media change question as no klass support"); return; } /* run the callback */ klass->media_change_question (task, state->request, state->results); return; } /* just re-run the transaction after a small delay */ if (state->exit_enum == PK_EXIT_ENUM_CANCELLED_PRIORITY) { state->retry_id = g_timeout_add (PK_TASK_TRANSACTION_CANCELLED_RETRY_TIMEOUT, pk_task_retry_cancelled_transaction_cb, g_steal_pointer (&task)); return; } /* we're done */ g_task_return_pointer (gtask, g_steal_pointer (&state->results), g_object_unref); } /** * pk_task_install_packages_async: * @task: a valid #PkTask instance * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Merges in details about packages using resolve. * * Since: 0.5.2 **/ void pk_task_install_packages_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_INSTALL_PACKAGES; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); if (task->priv->allow_reinstall) { pk_bitfield_add (state->transaction_flags, PK_TRANSACTION_FLAG_ENUM_ALLOW_REINSTALL); } if (task->priv->allow_downgrade) { pk_bitfield_add (state->transaction_flags, PK_TRANSACTION_FLAG_ENUM_ALLOW_DOWNGRADE); } state->package_ids = g_strdupv (package_ids); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (g_steal_pointer (>ask)); else pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_update_packages_async: * @task: a valid #PkTask instance * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * Update specific packages to the newest available versions. * * Since: 0.5.2 **/ void pk_task_update_packages_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_UPDATE_PACKAGES; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->package_ids = g_strdupv (package_ids); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (g_steal_pointer (>ask)); else pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_upgrade_system_async: * @task: a valid #PkTask instance * @distro_id: a distro ID such as "fedora-14" * @upgrade_kind: a #PkUpgradeKindEnum such as %PK_UPGRADE_KIND_ENUM_COMPLETE * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * This transaction will update the distro to the next version, which may * involve just downloading the installer and setting up the boot device, * or may involve doing an on-line upgrade. * * The backend will decide what is best to do. * * Since: 1.0.12 **/ void pk_task_upgrade_system_async (PkTask *task, const gchar *distro_id, PkUpgradeKindEnum upgrade_kind, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_UPGRADE_SYSTEM; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->distro_id = g_strdup (distro_id); state->upgrade_kind = upgrade_kind; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_upgrade_system_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (g_steal_pointer (>ask)); else pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_remove_packages_async: * @task: a valid #PkTask instance * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @allow_deps: if other dependent packages are allowed to be removed from the computer * @autoremove: if other packages installed at the same time should be tried to remove * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * Remove a package (optionally with dependancies) from the system. * If @allow_deps is set to %FALSE, and other packages would have to be removed, * then the transaction would fail. * * Since: 0.5.2 **/ void pk_task_remove_packages_async (PkTask *task, gchar **package_ids, gboolean allow_deps, gboolean autoremove, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_REMOVE_PACKAGES; state->allow_deps = allow_deps; state->autoremove = autoremove; state->package_ids = g_strdupv (package_ids); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (g_steal_pointer (>ask)); else pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_install_files_async: * @task: a valid #PkTask instance * @files: (array zero-terminated=1): a file such as "/home/hughsie/Desktop/hal-devel-0.10.0.rpm" * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * Install a file locally, and get the deps from the repositories. * This is useful for double clicking on a .rpm or .deb file. * * Since: 0.5.2 **/ void pk_task_install_files_async (PkTask *task, gchar **files, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_INSTALL_FILES; if (task->priv->only_trusted) state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); else state->transaction_flags = 0; state->files = g_strdupv (files); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_files_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (g_steal_pointer (>ask)); else pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_resolve_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @packages: (array zero-terminated=1): package names to find * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Resolves a package name to a package-id. * * Since: 0.6.5 **/ void pk_task_resolve_async (PkTask *task, PkBitfield filters, gchar **packages, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_RESOLVE; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); if (task->priv->allow_downgrade) pk_bitfield_add (state->transaction_flags, PK_TRANSACTION_FLAG_ENUM_ALLOW_DOWNGRADE); if (task->priv->allow_reinstall) pk_bitfield_add (state->transaction_flags, PK_TRANSACTION_FLAG_ENUM_ALLOW_REINSTALL); state->filters = filters; state->packages = g_strdupv (packages); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_resolve_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_search_names_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: (array zero-terminated=1): search values * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Searches for a package name. * * Since: 0.6.5 **/ void pk_task_search_names_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_SEARCH_NAME; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_search_names_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_search_details_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: (array zero-terminated=1): search values * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Searches for some package details. * * Since: 0.6.5 **/ void pk_task_search_details_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_SEARCH_DETAILS; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_search_details_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_search_groups_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: (array zero-terminated=1): search values * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Searches the group lists. * * Since: 0.6.5 **/ void pk_task_search_groups_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_SEARCH_GROUP; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_search_groups_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_search_files_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: (array zero-terminated=1): search values * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Searches for specific files. * * Since: 0.6.5 **/ void pk_task_search_files_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_SEARCH_FILE; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_files_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_get_details_async: * @task: a valid #PkTask instance * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Gets details about packages. * * Since: 0.6.5 **/ void pk_task_get_details_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_DETAILS; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->package_ids = g_strdupv (package_ids); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_get_details_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_get_update_detail_async: * @task: a valid #PkTask instance * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Gets details about updates. * * Since: 0.6.5 **/ void pk_task_get_update_detail_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_UPDATE_DETAIL; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->package_ids = g_strdupv (package_ids); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_get_update_detail_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_download_packages_async: * @task: a valid #PkTask instance * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @directory: the destination directory * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Downloads packages * * Since: 0.6.5 **/ void pk_task_download_packages_async (PkTask *task, gchar **package_ids, const gchar *directory, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_DOWNLOAD_PACKAGES; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->package_ids = g_strdupv (package_ids); state->directory = g_strdup (directory); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_download_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_get_updates_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Gets the update lists. * * Since: 0.6.5 **/ void pk_task_get_updates_async (PkTask *task, PkBitfield filters, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_UPDATES; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_get_updates_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_depends_on_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @recursive: if we should recurse to packages that depend on other packages * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Get the list of dependant packages. * * Since: 0.6.5 **/ void pk_task_depends_on_async (PkTask *task, PkBitfield filters, gchar **package_ids, gboolean recursive, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_DEPENDS_ON; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->package_ids = g_strdupv (package_ids); state->recursive = recursive; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_depends_on_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_get_packages_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Gets the list of packages. * * Since: 0.6.5 **/ void pk_task_get_packages_async (PkTask *task, PkBitfield filters, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_PACKAGES; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_required_by_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @recursive: if we should return packages that depend on the ones we do * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Get the packages this package requires. * * Since: 0.6.5 **/ void pk_task_required_by_async (PkTask *task, PkBitfield filters, gchar **package_ids, gboolean recursive, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_REQUIRED_BY; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->package_ids = g_strdupv (package_ids); state->recursive = recursive; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_what_provides_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: (array zero-terminated=1): values to search for * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Find the package that provides some resource. * * Since: 0.6.5 **/ void pk_task_what_provides_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_WHAT_PROVIDES; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_get_files_async: * @task: a valid #PkTask instance * @package_ids: (array zero-terminated=1): a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Get the files in a package. * * Since: 0.6.5 **/ void pk_task_get_files_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_FILES; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->package_ids = g_strdupv (package_ids); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_get_categories_async: * @task: a valid #PkTask instance * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: (scope async): the function to run on completion * @user_data: the data to pass to @callback * * Get the categories available. * * Since: 0.6.5 **/ void pk_task_get_categories_async (PkTask *task, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_CATEGORIES; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_refresh_cache_async: * @task: a valid #PkTask instance * @force: if the metadata should be deleted and re-downloaded even if it is correct * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Refresh the package cache. * * Since: 0.6.5 **/ void pk_task_refresh_cache_async (PkTask *task, gboolean force, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_REFRESH_CACHE; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->force = force; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_get_repo_list_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Get the list of available repositories. * * Since: 0.6.5 **/ void pk_task_get_repo_list_async (PkTask *task, PkBitfield filters, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_REPO_LIST; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->filters = filters; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_repo_enable_async: * @task: a valid #PkTask instance * @repo_id: The software repository ID * @enabled: %TRUE or %FALSE * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback * * Enable or disable a specific repo. * * Since: 0.6.5 **/ void pk_task_repo_enable_async (PkTask *task, const gchar *repo_id, gboolean enabled, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_REPO_ENABLE; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->repo_id = g_strdup (repo_id); state->enabled = enabled; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_install_packages_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* run task with callbacks */ pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_repair_system_async: * @task: a valid #PkTask instance * @cancellable: a #GCancellable or %NULL * @progress_callback: (scope notified): the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * Recover the system from broken dependencies and aborted installations. * * Since: 0.7.2 **/ void pk_task_repair_system_async (PkTask *task, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { PkTaskState *state; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_autoptr(GTask) gtask = NULL; g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_REPAIR_SYSTEM; state->transaction_flags = pk_bitfield_value (PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); gtask = g_task_new (task, cancellable, callback_ready, user_data); g_task_set_source_tag (gtask, pk_task_repair_system_async); g_debug ("adding state %p", state); g_hash_table_insert (task->priv->gtasks, GUINT_TO_POINTER (state->request), g_object_ref (gtask)); g_task_set_task_data (gtask, g_steal_pointer (&state), pk_task_state_free); /* start trusted repair system async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (g_steal_pointer (>ask)); else pk_task_do_async_action (g_steal_pointer (>ask)); } /** * pk_task_generic_finish: * @task: a valid #PkTask instance * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: (transfer full): The #PkResults of the transaction. * * Since: 0.5.2 **/ PkResults * pk_task_generic_finish (PkTask *task, GAsyncResult *res, GError **error) { GTask *gtask; PkTaskState *state; g_return_val_if_fail (PK_IS_TASK (task), NULL); g_return_val_if_fail (g_task_is_valid (res, task), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); gtask = G_TASK (res); state = g_task_get_task_data (gtask); /* remove from table */ g_debug ("remove state %p", state); g_hash_table_remove (task->priv->gtasks, GUINT_TO_POINTER (state->request)); return g_task_propagate_pointer (gtask, error); } /** * pk_task_set_simulate: * @task: a valid #PkTask instance * @simulate: the simulate mode * * If the simulate step should be run without the actual transaction. * * Since: 0.6.10 **/ void pk_task_set_simulate (PkTask *task, gboolean simulate) { g_return_if_fail (PK_IS_TASK (task)); task->priv->simulate = simulate; g_object_notify (G_OBJECT (task), "simulate"); } /** * pk_task_get_simulate: * @task: a valid #PkTask instance * * Gets if we are simulating. * * Return value: %TRUE if we are simulating * * Since: 0.6.10 **/ gboolean pk_task_get_simulate (PkTask *task) { g_return_val_if_fail (PK_IS_TASK (task), FALSE); return task->priv->simulate; } /** * pk_task_set_only_download: * @task: a valid #PkTask instance * @only_download: %FALSE to actually commit the transaction * * If the transaction should be prepared (depsolved, packages * downloaded, etc) but not committed. * * Since: 0.8.1 **/ void pk_task_set_only_download (PkTask *task, gboolean only_download) { g_return_if_fail (PK_IS_TASK (task)); task->priv->only_download = only_download; g_object_notify (G_OBJECT (task), "only-download"); } /** * pk_task_get_only_download: * @task: a valid #PkTask instance * * Gets if we are just preparing the transaction for later. * * Return value: %TRUE if only downloading * * Since: 0.8.1 **/ gboolean pk_task_get_only_download (PkTask *task) { g_return_val_if_fail (PK_IS_TASK (task), FALSE); return task->priv->only_download; } /** * pk_task_set_only_trusted: * @task: a valid #PkTask instance * @only_trusted: %TRUE to allow only authenticated packages * * If only authenticated packages should be allowed in the * transaction. * * Since: 0.9.5 **/ void pk_task_set_only_trusted (PkTask *task, gboolean only_trusted) { g_return_if_fail (PK_IS_TASK (task)); task->priv->only_trusted = only_trusted; g_object_notify (G_OBJECT (task), "only-trusted"); } /** * pk_task_get_only_trusted: * @task: a valid #PkTask instance * * Gets if we allow only authenticated packages in the transactoin. * * Return value: %TRUE if we allow only authenticated packages * * Since: 0.9.5 **/ gboolean pk_task_get_only_trusted (PkTask *task) { g_return_val_if_fail (PK_IS_TASK (task), FALSE); return task->priv->only_trusted; } /** * pk_task_set_allow_downgrade: * @task: a valid #PkTask instance * @allow_downgrade: %TRUE to allow packages to be downgraded. * * If package downgrades shall be allowed during transaction. * * Since: 1.0.2 **/ void pk_task_set_allow_downgrade (PkTask *task, gboolean allow_downgrade) { g_return_if_fail (PK_IS_TASK (task)); task->priv->allow_downgrade = allow_downgrade; g_object_notify (G_OBJECT (task), "allow-downgrade"); } /** * pk_task_get_allow_downgrade: * @task: a valid #PkTask instance * * Gets if we are allow packages to be downgraded. * * Return value: %TRUE if package downgrades are allowed * * Since: 1.0.2 **/ gboolean pk_task_get_allow_downgrade (PkTask *task) { g_return_val_if_fail (PK_IS_TASK (task), FALSE); return task->priv->allow_downgrade; } /** * pk_task_set_allow_reinstall: * @task: a valid #PkTask instance * @allow_reinstall: %TRUE to allow packages to be reinstalled. * * If package reinstallation shall be allowed during transaction. * * Since: 1.0.2 **/ void pk_task_set_allow_reinstall (PkTask *task, gboolean allow_reinstall) { g_return_if_fail (PK_IS_TASK (task)); task->priv->allow_reinstall = allow_reinstall; g_object_notify (G_OBJECT (task), "allow-reinstall"); } /** * pk_task_get_allow_reinstall: * @task: a valid #PkTask instance * * Gets if we allow packages to be reinstalled. * * Return value: %TRUE if package reinstallation is allowed * * Since: 1.0.2 **/ gboolean pk_task_get_allow_reinstall (PkTask *task) { g_return_val_if_fail (PK_IS_TASK (task), FALSE); return task->priv->allow_reinstall; } /* * pk_task_get_property: **/ static void pk_task_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { PkTask *task = PK_TASK (object); PkTaskPrivate *priv = task->priv; switch (prop_id) { case PROP_SIMULATE: g_value_set_boolean (value, priv->simulate); break; case PROP_ONLY_PREPARE: g_value_set_boolean (value, priv->only_download); break; case PROP_ONLY_TRUSTED: g_value_set_boolean (value, priv->only_trusted); break; case PROP_ALLOW_REINSTALL: g_value_set_boolean (value, priv->allow_reinstall); break; case PROP_ALLOW_DOWNGRADE: g_value_set_boolean (value, priv->allow_downgrade); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /* * pk_task_set_property: **/ static void pk_task_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { PkTask *task = PK_TASK (object); PkTaskPrivate *priv = task->priv; switch (prop_id) { case PROP_SIMULATE: priv->simulate = g_value_get_boolean (value); break; case PROP_ONLY_PREPARE: priv->only_download = g_value_get_boolean (value); break; case PROP_ONLY_TRUSTED: priv->only_trusted = g_value_get_boolean (value); break; case PROP_ALLOW_REINSTALL: priv->allow_reinstall = g_value_get_boolean (value); break; case PROP_ALLOW_DOWNGRADE: priv->allow_downgrade = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /* * pk_task_class_init: **/ static void pk_task_class_init (PkTaskClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = pk_task_finalize; object_class->get_property = pk_task_get_property; object_class->set_property = pk_task_set_property; /** * PkTask:simulate: * * %TRUE if we are simulating. * * Since: 0.5.2 */ pspec = g_param_spec_boolean ("simulate", NULL, NULL, TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_SIMULATE, pspec); /** * PkTask:only-download: * * %TRUE if we are just preparing the transaction for later. * * Since: 0.8.1 */ pspec = g_param_spec_boolean ("only-download", NULL, NULL, FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_ONLY_PREPARE, pspec); /** * PkTask:only-trusted: * * %TRUE if only authenticated packages should be allowed in the transaction. * * Since: 0.9.5 */ pspec = g_param_spec_boolean ("only-trusted", NULL, NULL, TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_ONLY_TRUSTED, pspec); /** * PkTask:allow-reinstall: * * %TRUE if package reinstallation shall be allowed during transaction. * * Since: 1.0.2 */ pspec = g_param_spec_boolean ("allow-reinstall", NULL, NULL, FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_ALLOW_REINSTALL, pspec); /** * PkTask:allow-downgrade: * * %TRUE if package downgrades are allowed. * * Since: 1.0.2 */ pspec = g_param_spec_boolean ("allow-downgrade", NULL, NULL, FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_ALLOW_DOWNGRADE, pspec); g_type_class_add_private (klass, sizeof (PkTaskPrivate)); } /* * pk_task_init: **/ static void pk_task_init (PkTask *task) { task->priv = PK_TASK_GET_PRIVATE (task); task->priv->gtasks = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); task->priv->simulate = TRUE; task->priv->allow_reinstall = FALSE; task->priv->allow_downgrade = FALSE; } /* * pk_task_finalize: **/ static void pk_task_finalize (GObject *object) { PkTask *task = PK_TASK (object); g_clear_pointer (&task->priv->gtasks, g_hash_table_unref); G_OBJECT_CLASS (pk_task_parent_class)->finalize (object); } /** * pk_task_new: * * Return value: a new #PkTask object. * * Since: 0.5.2 **/ PkTask * pk_task_new (void) { PkTask *task; task = g_object_new (PK_TYPE_TASK, NULL); return PK_TASK (task); }