/** * gs_plugin_update_app: */ gboolean gs_plugin_update_app (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autoptr(XdgAppInstalledRef) xref = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* install */ gs_app_set_state (app, AS_APP_STATE_INSTALLING); xref = xdg_app_installation_update (priv->installation, XDG_APP_UPDATE_FLAGS_NONE, gs_app_get_xdgapp_kind (app), gs_app_get_xdgapp_name (app), gs_app_get_xdgapp_arch (app), gs_app_get_xdgapp_branch (app), gs_plugin_xdg_app_progress_cb, app, cancellable, error); if (xref == NULL) { gs_app_set_state_recover (app); return FALSE; } /* state is known */ gs_app_set_state (app, AS_APP_STATE_INSTALLED); return TRUE; }
gboolean gs_plugin_app_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autoptr(SnapdClient) client = NULL; SnapdInstallFlags flags = SNAPD_INSTALL_FLAGS_NONE; /* We can only install apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; client = get_client (plugin, error); if (client == NULL) return FALSE; gs_app_set_state (app, AS_APP_STATE_INSTALLING); if (g_strcmp0 (gs_app_get_metadata_item (app, "snap::confinement"), "classic") == 0) flags |= SNAPD_INSTALL_FLAGS_CLASSIC; if (!snapd_client_install2_sync (client, flags, gs_app_get_metadata_item (app, "snap::name"), NULL, NULL, progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); snapd_error_convert (error); return FALSE; } gs_app_set_state (app, AS_APP_STATE_INSTALLED); return TRUE; }
/** * gs_plugin_app_remove: */ gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* remove */ gs_app_set_state (app, AS_APP_STATE_REMOVING); if (!xdg_app_installation_uninstall (priv->installation, XDG_APP_REF_KIND_APP, gs_app_get_xdgapp_name (app), gs_app_get_xdgapp_arch (app), gs_app_get_xdgapp_branch (app), gs_plugin_xdg_app_progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); return FALSE; } /* state is not known: we don't know if we can re-install this app */ gs_app_set_state (app, AS_APP_STATE_UNKNOWN); return TRUE; }
/** * gs_plugin_refine_app: */ static gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GError **error) { LiPkgInfo *pki; g_autoptr(GError) error_local = NULL; /* sanity check */ if (gs_app_get_source_default (app) == NULL) return TRUE; pki = li_manager_get_software_by_pkid (plugin->priv->mgr, gs_app_get_source_default (app), &error_local); if (error_local != NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Unable to refine metadata: %s", error_local->message); return FALSE; } if (pki == NULL) return TRUE; if (li_pkg_info_has_flag (pki, LI_PACKAGE_FLAG_INSTALLED)) gs_app_set_state (app, AS_APP_STATE_INSTALLED); else gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_version (app, li_pkg_info_get_version (pki)); return TRUE; }
/** * gs_plugin_app_remove: */ gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { const gchar *epi_desktop; g_autofree gchar *basename = NULL; g_autofree gchar *app_desktop = NULL; g_autoptr(GFile) file_epi = NULL; g_autoptr(GFile) file_app = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "Epiphany") != 0) return TRUE; epi_desktop = gs_app_get_source_id_default (app); if (epi_desktop == NULL) return TRUE; /* remove the epi 'config' file */ gs_app_set_state (app, AS_APP_STATE_REMOVING); file_epi = g_file_new_for_path (epi_desktop); if (!g_file_delete (file_epi, NULL, error)) return FALSE; /* remove the shared desktop file */ basename = g_file_get_basename (file_epi); app_desktop = g_build_filename (g_get_user_data_dir (), "applications", gs_app_get_id (app), NULL); file_app = g_file_new_for_path (app_desktop); if (!g_file_delete (file_app, NULL, error)) return FALSE; gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autoptr(SnapdClient) client = NULL; /* We can only remove apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; client = get_client (plugin, error); if (client == NULL) return FALSE; gs_app_set_state (app, AS_APP_STATE_REMOVING); if (!snapd_client_remove_sync (client, gs_app_get_metadata_item (app, "snap::name"), progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); snapd_error_convert (error); return FALSE; } gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
static gboolean gs_plugin_fwupd_modify_source (GsPlugin *plugin, GsApp *app, gboolean enabled, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); const gchar *remote_id = gs_app_get_metadata_item (app, "fwupd::remote-id"); if (remote_id == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "not enough data for fwupd %s", gs_app_get_unique_id (app)); return FALSE; } gs_app_set_state (app, enabled ? AS_APP_STATE_INSTALLING : AS_APP_STATE_REMOVING); if (!fwupd_client_modify_remote (priv->client, remote_id, "Enabled", enabled ? "true" : "false", cancellable, error)) { gs_app_set_state_recover (app); return FALSE; } gs_app_set_state (app, enabled ? AS_APP_STATE_INSTALLED : AS_APP_STATE_AVAILABLE); return TRUE; }
/** * gs_plugin_refine_item_state: */ static gboolean gs_plugin_refine_item_state (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); guint i; g_autoptr(GPtrArray) xrefs = NULL; g_autoptr(AsProfileTask) ptask = NULL; /* already found */ if (gs_app_get_state (app) != AS_APP_STATE_UNKNOWN) return TRUE; /* need broken out metadata */ if (!gs_plugin_refine_item_metadata (plugin, app, cancellable, error)) return FALSE; /* get apps and runtimes */ ptask = as_profile_start_literal (gs_plugin_get_profile (plugin), "xdg-app::refine-action"); xrefs = xdg_app_installation_list_installed_refs (priv->installation, cancellable, error); if (xrefs == NULL) return FALSE; for (i = 0; i < xrefs->len; i++) { XdgAppInstalledRef *xref = g_ptr_array_index (xrefs, i); /* check xref is app */ if (!gs_plugin_xdg_app_is_xref (app, XDG_APP_REF(xref))) continue; /* mark as installed */ g_debug ("marking %s as installed with xdg-app", gs_app_get_id (app)); gs_plugin_xdg_app_set_metadata_installed (app, xref); if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN) gs_app_set_state (app, AS_APP_STATE_INSTALLED); } /* anything not installed just check the remote is still present */ if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN && gs_app_get_origin (app) != NULL) { g_autoptr(XdgAppRemote) xremote = NULL; xremote = xdg_app_installation_get_remote_by_name (priv->installation, gs_app_get_origin (app), cancellable, NULL); if (xremote != NULL) { g_debug ("marking %s as available with xdg-app", gs_app_get_id (app)); gs_app_set_state (app, AS_APP_STATE_AVAILABLE); } } /* success */ return TRUE; }
static gboolean gs_plugin_fwupd_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); const gchar *device_id; FwupdInstallFlags install_flags = 0; GFile *local_file; g_autofree gchar *filename = NULL; /* not set */ local_file = gs_app_get_local_file (app); if (local_file == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "not enough data for fwupd %s", filename); return FALSE; } /* file does not yet exist */ filename = g_file_get_path (local_file); if (!g_file_query_exists (local_file, cancellable)) { const gchar *uri = gs_fwupd_app_get_update_uri (app); gs_app_set_state (app, AS_APP_STATE_INSTALLING); if (!gs_plugin_download_file (plugin, app, uri, filename, cancellable, error)) return FALSE; } /* limit to single device? */ device_id = gs_fwupd_app_get_device_id (app); if (device_id == NULL) device_id = FWUPD_DEVICE_ID_ANY; /* set the last object */ g_set_object (&priv->app_current, app); /* only offline supported */ if (gs_app_get_metadata_item (app, "fwupd::OnlyOffline") != NULL) install_flags |= FWUPD_INSTALL_FLAG_OFFLINE; gs_app_set_state (app, AS_APP_STATE_INSTALLING); if (!fwupd_client_install (priv->client, device_id, filename, install_flags, cancellable, error)) { gs_plugin_fwupd_error_convert (error); gs_app_set_state_recover (app); return FALSE; } /* delete the file from the cache */ gs_app_set_state (app, AS_APP_STATE_INSTALLED); return g_file_delete (local_file, cancellable, error); }
gboolean gs_plugin_app_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autoptr(LiInstaller) inst = NULL; GsPluginHelper helper; g_autoptr(GError) error_local = NULL; /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* create new installer and select remote package */ inst = li_installer_new (); li_installer_open_remote (inst, gs_app_get_source_default (app), &error_local); if (error_local != NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to install software: %s", error_local->message); return FALSE; } /* set up progress forwarding */ helper.app = app; helper.plugin = plugin; g_signal_connect (inst, "progress", G_CALLBACK (gs_plugin_installer_progress_cb), &helper); /* install software */ gs_app_set_state (app, AS_APP_STATE_INSTALLING); li_installer_install (inst, &error_local); if (error_local != NULL) { gs_app_set_state (app, AS_APP_STATE_AVAILABLE); g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to install software: %s", error_local->message); return FALSE; } gs_app_set_state (app, AS_APP_STATE_INSTALLED); return TRUE; }
gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); LiPkgInfo *pki; g_autoptr(GError) error_local = NULL; g_autoptr(AsProfileTask) ptask = NULL; /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* profile */ ptask = as_profile_start (gs_plugin_get_profile (plugin), "limba::refine{%s}", gs_app_get_id (app)); /* sanity check */ if (gs_app_get_source_default (app) == NULL) return TRUE; pki = li_manager_get_software_by_pkid (priv->mgr, gs_app_get_source_default (app), &error_local); if (error_local != NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Unable to refine metadata: %s", error_local->message); return FALSE; } if (pki == NULL) return TRUE; if (li_pkg_info_has_flag (pki, LI_PACKAGE_FLAG_INSTALLED)) gs_app_set_state (app, AS_APP_STATE_INSTALLED); else gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_version (app, li_pkg_info_get_version (pki)); return TRUE; }
/** * gs_plugin_add_updates: */ gboolean gs_plugin_add_updates (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); guint i; g_autoptr(GPtrArray) xrefs = NULL; /* get all the installed apps (no network I/O) */ xrefs = xdg_app_installation_list_installed_refs (priv->installation, cancellable, error); if (xrefs == NULL) return FALSE; for (i = 0; i < xrefs->len; i++) { XdgAppInstalledRef *xref = g_ptr_array_index (xrefs, i); const gchar *commit; const gchar *latest_commit; g_autoptr(GsApp) app = NULL; g_autoptr(GError) error_local = NULL; /* check the application has already been downloaded */ commit = xdg_app_ref_get_commit (XDG_APP_REF (xref)); latest_commit = xdg_app_installed_ref_get_latest_commit (xref); if (g_strcmp0 (commit, latest_commit) == 0) { g_debug ("no downloaded update for %s", xdg_app_ref_get_name (XDG_APP_REF (xref))); continue; } /* we have an update to show */ g_debug ("%s has a downloaded update %s->%s", xdg_app_ref_get_name (XDG_APP_REF (xref)), commit, latest_commit); app = gs_plugin_xdg_app_create_installed (plugin, xref, &error_local); if (app == NULL) { g_warning ("failed to add xdg-app: %s", error_local->message); continue; } if (gs_app_get_state (app) == AS_APP_STATE_INSTALLED) gs_app_set_state (app, AS_APP_STATE_UNKNOWN); gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); gs_app_list_add (list, app); } return TRUE; }
static GsApp* gs_plugin_app_from_pki (LiPkgInfo *pki) { const gchar *cptkind_str; GsApp *app; cptkind_str = li_pkg_info_get_component_kind (pki); if ((cptkind_str != NULL) && (g_strcmp0 (cptkind_str, "desktop") == 0)) { g_autofree gchar *tmp = NULL; /* type=desktop AppStream components result in a Limba bundle name which has the .desktop stripped away. * We need to re-add it for GNOME Software. * In any other case, the Limba bundle name equals the AppStream ID of the component it contains */ tmp = g_strdup_printf ("%s.desktop", li_pkg_info_get_name (pki)); app = gs_app_new (tmp); gs_app_set_kind (app, AS_APP_KIND_DESKTOP); } else { app = gs_app_new (li_pkg_info_get_name (pki)); gs_app_set_kind (app, AS_APP_KIND_GENERIC); } /* TODO: scope?, branch? */ gs_app_set_management_plugin (app, "limba"); gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_LIMBA); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, li_pkg_info_get_name (pki)); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, li_pkg_info_get_name (pki)); gs_app_set_version (app, li_pkg_info_get_version (pki)); gs_app_add_source (app, li_pkg_info_get_id (pki)); return app; }
static void gs_plugin_fwupd_notify_status_cb (GObject *object, GParamSpec *pspec, GsPlugin *plugin) { GsPluginData *priv = gs_plugin_get_data (plugin); /* nothing in progress */ if (priv->app_current == NULL) { g_debug ("fwupd status: %s", fwupd_status_to_string (fwupd_client_get_status (priv->client))); return; } g_debug ("fwupd status for %s: %s", gs_app_get_unique_id (priv->app_current), fwupd_status_to_string (fwupd_client_get_status (priv->client))); switch (fwupd_client_get_status (priv->client)) { case FWUPD_STATUS_DECOMPRESSING: case FWUPD_STATUS_DEVICE_RESTART: case FWUPD_STATUS_DEVICE_WRITE: case FWUPD_STATUS_DEVICE_VERIFY: gs_app_set_state (priv->app_current, AS_APP_STATE_INSTALLING); break; case FWUPD_STATUS_IDLE: g_clear_object (&priv->app_current); break; default: break; } }
static GsApp * gs_plugin_generic_updates_get_os_update (GsPlugin *plugin) { GsApp *app; const gchar *id = "org.gnome.Software.OsUpdate"; g_autoptr(AsIcon) ic = NULL; /* create new */ app = gs_app_new (id); gs_app_add_quirk (app, GS_APP_QUIRK_IS_PROXY); gs_app_set_management_plugin (app, ""); gs_app_set_kind (app, AS_APP_KIND_OS_UPDATE); gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, /* TRANSLATORS: this is a group of updates that are not * packages and are not shown in the main list */ _("OS Updates")); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, /* TRANSLATORS: this is a longer description of the * "OS Updates" string */ _("Includes performance, stability and security improvements.")); gs_app_set_description (app, GS_APP_QUALITY_NORMAL, gs_app_get_summary (app)); ic = as_icon_new (); as_icon_set_kind (ic, AS_ICON_KIND_STOCK); as_icon_set_name (ic, "software-update-available-symbolic"); gs_app_add_icon (app, ic); return app; }
gboolean gs_plugin_add_sources (GsPlugin *plugin, GsAppList *list, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); PkBitfield filter; PkRepoDetail *rd; ProgressData data; const gchar *id; guint i; g_autoptr(GHashTable) hash = NULL; g_autoptr(PkResults) results = NULL; g_autoptr(GPtrArray) array = NULL; data.app = NULL; data.plugin = plugin; data.ptask = NULL; /* ask PK for the repo details */ filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_SOURCE, PK_FILTER_ENUM_NOT_SUPPORTED, -1); results = pk_client_get_repo_list (PK_CLIENT(priv->task), filter, cancellable, gs_plugin_packagekit_progress_cb, &data, error); if (!gs_plugin_packagekit_results_valid (results, error)) return FALSE; hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); array = pk_results_get_repo_detail_array (results); for (i = 0; i < array->len; i++) { g_autoptr(GsApp) app = NULL; rd = g_ptr_array_index (array, i); id = pk_repo_detail_get_id (rd); app = gs_app_new (id); gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); gs_app_set_kind (app, AS_APP_KIND_SOURCE); gs_app_set_state (app, pk_repo_detail_get_enabled (rd) ? AS_APP_STATE_INSTALLED : AS_APP_STATE_AVAILABLE); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, pk_repo_detail_get_description (rd)); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, pk_repo_detail_get_description (rd)); gs_app_list_add (list, app); g_hash_table_insert (hash, g_strdup (id), (gpointer) app); } /* get every application on the system and add it as a related package * if it matches */ return gs_plugin_add_sources_related (plugin, hash, cancellable, error); }
/** * gs_plugin_app_upgrade_download: */ gboolean gs_plugin_app_upgrade_download (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); ProgressData data; g_autoptr(PkResults) results = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0) return TRUE; data.app = app; data.plugin = plugin; /* check is distro-upgrade */ if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "app %s is not a distro upgrade", gs_app_get_id (app)); return FALSE; } /* ask PK to download enough packages to upgrade the system */ gs_app_set_state (app, AS_APP_STATE_INSTALLING); results = pk_task_upgrade_system_sync (priv->task, gs_app_get_version (app), PK_UPGRADE_KIND_ENUM_COMPLETE, cancellable, gs_plugin_packagekit_progress_cb, &data, error); if (!gs_plugin_packagekit_results_valid (results, error)) { gs_app_set_state_recover (app); return FALSE; } /* state is known */ gs_app_set_state (app, AS_APP_STATE_UPDATABLE); return TRUE; }
gboolean gs_plugin_add_updates (GsPlugin *plugin, GsAppList *list, GCancellable *cancellable, GError **error) { guint i; g_autoptr(GError) error_local = NULL; g_auto(GStrv) package_ids = NULL; /* get the id's if the file exists */ package_ids = pk_offline_get_prepared_ids (&error_local); if (package_ids == NULL) { if (g_error_matches (error_local, PK_OFFLINE_ERROR, PK_OFFLINE_ERROR_NO_DATA)) { return TRUE; } g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "Failed to get prepared IDs: %s", error_local->message); return FALSE; } /* add them to the new array */ for (i = 0; package_ids[i] != NULL; i++) { g_autoptr(GsApp) app = NULL; g_auto(GStrv) split = NULL; /* search in the cache */ app = gs_plugin_cache_lookup (plugin, package_ids[i]); if (app != NULL) { gs_app_list_add (list, app); continue; } /* create new app */ app = gs_app_new (NULL); gs_app_add_quirk (app, AS_APP_QUIRK_NEEDS_REBOOT); gs_app_set_management_plugin (app, "packagekit"); gs_app_add_source_id (app, package_ids[i]); split = pk_package_id_split (package_ids[i]); gs_app_add_source (app, split[PK_PACKAGE_ID_NAME]); gs_app_set_update_version (app, split[PK_PACKAGE_ID_VERSION]); gs_app_set_state (app, AS_APP_STATE_UPDATABLE); gs_app_set_kind (app, AS_APP_KIND_GENERIC); gs_app_set_size_download (app, 0); gs_app_list_add (list, app); /* save in the cache */ gs_plugin_cache_add (plugin, package_ids[i], app); } return TRUE; }
gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autoptr(LiManager) mgr = NULL; GsPluginHelper helper; g_autoptr(GError) error_local = NULL; /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; mgr = li_manager_new (); /* set up progress forwarding */ helper.app = app; helper.plugin = plugin; g_signal_connect (mgr, "progress", G_CALLBACK (gs_plugin_manager_progress_cb), &helper); gs_app_set_state (app, AS_APP_STATE_REMOVING); li_manager_remove_software (mgr, gs_app_get_source_default (app), &error_local); if (error_local != NULL) { gs_app_set_state (app, AS_APP_STATE_INSTALLED); g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to remove software: %s", error_local->message); return FALSE; } gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autofree gchar *macaroon = NULL; g_auto(GStrv) discharges = NULL; /* We can only remove apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; get_macaroon (plugin, &macaroon, &discharges); gs_app_set_state (app, AS_APP_STATE_REMOVING); if (!gs_snapd_remove (macaroon, discharges, gs_app_get_id (app), progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); return FALSE; } gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
/** * gs_plugin_refine_app: */ static gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GError **error) { g_autofree gchar *fn = NULL; g_autofree gchar *hash = NULL; g_autofree gchar *id_nonfull = NULL; id_nonfull = _gs_app_get_id_nonfull (app); hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1, gs_app_get_name (app), -1); fn = g_strdup_printf ("%s/epiphany/app-%s-%s/%s-%s.desktop", g_get_user_config_dir (), id_nonfull, hash, id_nonfull, hash); if (g_file_test (fn, G_FILE_TEST_EXISTS)) { gs_app_set_state (app, AS_APP_STATE_INSTALLED); gs_app_add_source_id (app, fn); gs_app_set_management_plugin (app, "Epiphany"); return TRUE; } gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
/** * gs_plugin_add_popular: */ gboolean gs_plugin_add_popular (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { g_autoptr(GsApp) app = gs_app_new ("gnome-power-manager"); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Power Manager"); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "Power Management Program"); gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_kind (app, GS_APP_KIND_NORMAL); gs_plugin_add_app (list, app); gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP); return TRUE; }
/** * gs_plugin_add_installed: */ gboolean gs_plugin_add_installed (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autoptr(GError) error_md = NULL; g_autoptr(GPtrArray) xrefs = NULL; guint i; /* if we've never ever run before, get the AppStream data */ if (!gs_plugin_refresh_appstream (plugin, G_MAXUINT, cancellable, &error_md)) { g_warning ("failed to get initial available data: %s", error_md->message); } /* get apps and runtimes */ xrefs = xdg_app_installation_list_installed_refs (priv->installation, cancellable, error); if (xrefs == NULL) return FALSE; for (i = 0; i < xrefs->len; i++) { XdgAppInstalledRef *xref = g_ptr_array_index (xrefs, i); g_autoptr(GError) error_local = NULL; g_autoptr(GsApp) app = NULL; /* only apps */ if (xdg_app_ref_get_kind (XDG_APP_REF (xref)) != XDG_APP_REF_KIND_APP) continue; app = gs_plugin_xdg_app_create_installed (plugin, xref, &error_local); if (app == NULL) { g_warning ("failed to add xdg-app: %s", error_local->message); continue; } gs_app_set_state (app, AS_APP_STATE_INSTALLED); gs_app_list_add (list, app); } return TRUE; }
/** * gs_plugin_add_category_apps: */ gboolean gs_plugin_add_category_apps (GsPlugin *plugin, GsCategory *category, GList **list, GCancellable *cancellable, GError **error) { g_autoptr(GsApp) app = gs_app_new ("gnome-boxes"); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Boxes"); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "View and use virtual machines"); gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, "http://www.box.org"); gs_app_set_kind (app, GS_APP_KIND_NORMAL); gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file ("/usr/share/icons/hicolor/48x48/apps/gnome-boxes.png", NULL)); gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP); gs_plugin_add_app (list, app); return TRUE; }
gboolean gs_plugin_add_sources (GsPlugin *plugin, GsAppList *list, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autoptr(GPtrArray) remotes = NULL; /* find all remotes */ remotes = fwupd_client_get_remotes (priv->client, cancellable, error); if (remotes == NULL) return FALSE; for (guint i = 0; i < remotes->len; i++) { FwupdRemote *remote = g_ptr_array_index (remotes, i); g_autofree gchar *id = NULL; g_autoptr(GsApp) app = NULL; /* ignore these, they're built in */ if (fwupd_remote_get_kind (remote) != FWUPD_REMOTE_KIND_DOWNLOAD) continue; /* create something that we can use to enable/disable */ id = g_strdup_printf ("org.fwupd.%s.remote", fwupd_remote_get_id (remote)); app = gs_app_new (id); gs_app_set_kind (app, AS_APP_KIND_SOURCE); gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM); gs_app_set_state (app, fwupd_remote_get_enabled (remote) ? AS_APP_STATE_INSTALLED : AS_APP_STATE_AVAILABLE); gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, fwupd_remote_get_title (remote)); #if FWUPD_CHECK_VERSION(1,0,7) gs_app_set_agreement (app, fwupd_remote_get_agreement (remote)); #endif gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, fwupd_remote_get_metadata_uri (remote)); gs_app_set_metadata (app, "fwupd::remote-id", fwupd_remote_get_id (remote)); gs_app_set_management_plugin (app, "fwupd"); gs_app_list_add (list, app); } return TRUE; }
/** * gs_plugin_add_sources: */ gboolean gs_plugin_add_sources (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autoptr(GPtrArray) xremotes = NULL; guint i; xremotes = xdg_app_installation_list_remotes (priv->installation, cancellable, error); if (xremotes == NULL) return FALSE; for (i = 0; i < xremotes->len; i++) { XdgAppRemote *xremote = g_ptr_array_index (xremotes, i); g_autoptr(GsApp) app = NULL; /* apps installed from bundles add their own remote that only * can be used for updating that app only -- so hide them */ if (xdg_app_remote_get_noenumerate (xremote)) continue; app = gs_app_new (xdg_app_remote_get_name (xremote)); gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); gs_app_set_kind (app, AS_APP_KIND_SOURCE); gs_app_set_state (app, AS_APP_STATE_INSTALLED); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, xdg_app_remote_get_name (xremote)); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, xdg_app_remote_get_title (xremote)); gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, xdg_app_remote_get_url (xremote)); gs_app_list_add (list, app); } return TRUE; }
gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { const gchar *gameid; g_autofree gchar *cmdline = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* this is async as steam is a different process: FIXME: use D-Bus */ gs_app_set_state (app, AS_APP_STATE_REMOVING); gameid = gs_app_get_metadata_item (app, "X-Steam-GameID"); cmdline = g_strdup_printf ("steam steam://uninstall/%s", gameid); if (!g_spawn_command_line_sync (cmdline, NULL, NULL, NULL, error)) { gs_utils_error_convert_gio (error); return FALSE; } return TRUE; }
static GsApp * gs_plugin_fwupd_new_app_from_device_raw (GsPlugin *plugin, FwupdDevice *device) { GPtrArray *icons; g_autofree gchar *id = NULL; g_autoptr(GsApp) app = NULL; /* create a GsApp based on the device, not the release */ id = gs_plugin_fwupd_build_device_id (device); app = gs_app_new (id); gs_app_set_kind (app, AS_APP_KIND_FIRMWARE); gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM); gs_app_set_state (app, AS_APP_STATE_INSTALLED); gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE); gs_app_set_version (app, fwupd_device_get_version (device)); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, fwupd_device_get_name (device)); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, fwupd_device_get_summary (device)); gs_app_set_description (app, GS_APP_QUALITY_LOWEST, fwupd_device_get_description (device)); gs_app_set_origin (app, fwupd_device_get_vendor (device)); gs_fwupd_app_set_device_id (app, fwupd_device_get_id (device)); gs_app_set_management_plugin (app, "fwupd"); /* create icon */ icons = fwupd_device_get_icons (device); for (guint j = 0; j < icons->len; j++) { const gchar *icon = g_ptr_array_index (icons, j); g_autoptr(AsIcon) icon_tmp = as_icon_new (); if (g_str_has_prefix (icon, "/")) { as_icon_set_kind (icon_tmp, AS_ICON_KIND_LOCAL); as_icon_set_filename (icon_tmp, icon); } else { as_icon_set_kind (icon_tmp, AS_ICON_KIND_STOCK); as_icon_set_name (icon_tmp, icon); } gs_app_add_icon (app, icon_tmp); } return g_steal_pointer (&app); }
/** * gs_plugin_filename_to_app: */ gboolean gs_plugin_filename_to_app (GsPlugin *plugin, GList **list, const gchar *filename, GCancellable *cancellable, GError **error) { const gchar *package_id; gboolean supported; PkDetails *item; ProgressData data; g_autoptr (PkResults) results = NULL; g_autofree gchar *basename = NULL; g_autofree gchar *license_spdx = NULL; g_auto(GStrv) files = NULL; g_auto(GStrv) split = NULL; g_autoptr(GPtrArray) array = NULL; g_autoptr(GsApp) app = NULL; /* does this match any of the mimetypes we support */ if (!gs_plugin_packagekit_refresh_content_type_matches (filename, &supported, cancellable, error)) return FALSE; if (!supported) return TRUE; data.plugin = plugin; data.ptask = NULL; /* get details */ files = g_strsplit (filename, "\t", -1); pk_client_set_cache_age (PK_CLIENT (plugin->priv->task), G_MAXUINT); results = pk_client_get_details_local (PK_CLIENT (plugin->priv->task), files, cancellable, gs_plugin_packagekit_progress_cb, &data, error); if (results == NULL) return FALSE; /* get results */ array = pk_results_get_details_array (results); if (array->len == 0) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no details for %s", filename); return FALSE; } if (array->len > 1) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "too many details [%i] for %s", array->len, filename); return FALSE; } /* create application */ item = g_ptr_array_index (array, 0); app = gs_app_new (NULL); package_id = pk_details_get_package_id (item); split = pk_package_id_split (package_id); basename = g_path_get_basename (filename); gs_app_set_management_plugin (app, "PackageKit"); gs_app_set_kind (app, GS_APP_KIND_PACKAGE); gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL); if (pk_details_get_summary (item)) gs_app_set_name (app, GS_APP_QUALITY_LOWEST, pk_details_get_summary (item)); else gs_app_set_name (app, GS_APP_QUALITY_LOWEST, split[PK_PACKAGE_ID_NAME]); gs_app_set_version (app, split[PK_PACKAGE_ID_VERSION]); gs_app_set_metadata (app, "PackageKit::local-filename", filename); gs_app_set_origin (app, basename); gs_app_add_source (app, split[PK_PACKAGE_ID_NAME]); gs_app_add_source_id (app, package_id); gs_plugin_packagekit_refresh_set_text (app, pk_details_get_description (item)); gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, pk_details_get_url (item)); gs_app_set_size (app, pk_details_get_size (item)); license_spdx = as_utils_license_to_spdx (pk_details_get_license (item)); gs_app_set_licence (app, license_spdx, GS_APP_QUALITY_LOWEST); /* look for a desktop file so we can use a valid application id */ if (!gs_plugin_packagekit_refresh_guess_app_id (plugin, app, filename, cancellable, error)) return FALSE; gs_plugin_add_app (list, app); return TRUE; }
/** * gs_appstream_refine_app: */ gboolean gs_appstream_refine_app (GsPlugin *plugin, GsApp *app, AsApp *item, GError **error) { AsRelease *rel; GHashTable *urls; GPtrArray *pkgnames; GPtrArray *kudos; const gchar *tmp; guint i; /* set the kind to be more precise */ if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN || gs_app_get_kind (app) == AS_APP_KIND_GENERIC) { gs_app_set_kind (app, as_app_get_kind (item)); } /* is installed already */ if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN) { switch (as_app_get_source_kind (item)) { case AS_APP_SOURCE_KIND_APPDATA: case AS_APP_SOURCE_KIND_DESKTOP: gs_app_set_kind (app, AS_APP_KIND_DESKTOP); gs_app_set_state (app, AS_APP_STATE_INSTALLED); break; case AS_APP_SOURCE_KIND_METAINFO: gs_app_set_state (app, AS_APP_STATE_INSTALLED); break; case AS_APP_SOURCE_KIND_APPSTREAM: gs_app_set_state (app, as_app_get_state (item)); break; default: break; } } /* set management plugin automatically */ gs_refine_item_management_plugin (app, item); /* set id */ if (as_app_get_id (item) != NULL && gs_app_get_id (app) == NULL) gs_app_set_id (app, as_app_get_id (item)); /* set name */ tmp = as_app_get_name (item, NULL); if (tmp != NULL) { if (g_str_has_prefix (tmp, "(Nightly) ")) { tmp += 10; if (gs_app_get_metadata_item (app, "X-XdgApp-Tags") == NULL) gs_app_set_metadata (app, "X-XdgApp-Tags", "nightly"); } gs_app_set_name (app, GS_APP_QUALITY_HIGHEST, tmp); } /* set summary */ tmp = as_app_get_comment (item, NULL); if (tmp != NULL) { gs_app_set_summary (app, GS_APP_QUALITY_HIGHEST, tmp); } /* add urls */ urls = as_app_get_urls (item); if (g_hash_table_size (urls) > 0 && gs_app_get_url (app, AS_URL_KIND_HOMEPAGE) == NULL) { GList *l; g_autoptr(GList) keys = NULL; keys = g_hash_table_get_keys (urls); for (l = keys; l != NULL; l = l->next) { gs_app_set_url (app, as_url_kind_from_string (l->data), g_hash_table_lookup (urls, l->data)); } } /* set licence */ if (as_app_get_project_license (item) != NULL && gs_app_get_license (app) == NULL) gs_app_set_license (app, GS_APP_QUALITY_HIGHEST, as_app_get_project_license (item)); /* set keywords */ if (as_app_get_keywords (item, NULL) != NULL && gs_app_get_keywords (app) == NULL) { gs_app_set_keywords (app, as_app_get_keywords (item, NULL)); gs_app_add_kudo (app, GS_APP_KUDO_HAS_KEYWORDS); } /* set origin */ if (as_app_get_origin (item) != NULL && gs_app_get_origin (app) == NULL) { gs_app_set_origin (app, as_app_get_origin (item)); } /* set description */ tmp = as_app_get_description (item, NULL); if (tmp != NULL) { g_autofree gchar *from_xml = NULL; from_xml = as_markup_convert_simple (tmp, error); if (from_xml == NULL) { g_prefix_error (error, "trying to parse '%s': ", tmp); return FALSE; } gs_app_set_description (app, GS_APP_QUALITY_HIGHEST, from_xml); } /* set icon */ if (as_app_get_icon_default (item) != NULL && gs_app_get_pixbuf (app) == NULL) gs_refine_item_pixbuf (plugin, app, item); /* set categories */ if (as_app_get_categories (item) != NULL && gs_app_get_categories (app)->len == 0) gs_app_set_categories (app, as_app_get_categories (item)); /* set project group */ if (as_app_get_project_group (item) != NULL && gs_app_get_project_group (app) == NULL) gs_app_set_project_group (app, as_app_get_project_group (item)); /* this is a core application for the desktop and cannot be removed */ if (_as_app_has_compulsory_for_desktop (item, "GNOME") && gs_app_get_kind (app) == AS_APP_KIND_DESKTOP) gs_app_add_quirk (app, AS_APP_QUIRK_COMPULSORY); /* set id kind */ if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN) gs_app_set_kind (app, as_app_get_kind (item)); /* copy all the metadata */ gs_appstream_copy_metadata (app, item); /* set package names */ pkgnames = as_app_get_pkgnames (item); if (pkgnames->len > 0 && gs_app_get_sources(app)->len == 0) gs_app_set_sources (app, pkgnames); /* set addons */ gs_appstream_refine_add_addons (plugin, app, item); /* set screenshots */ gs_appstream_refine_add_screenshots (app, item); /* are the screenshots perfect */ if (gs_appstream_are_screenshots_perfect (item)) gs_app_add_kudo (app, GS_APP_KUDO_PERFECT_SCREENSHOTS); /* was this application released recently */ if (gs_appstream_is_recent_release (item)) gs_app_add_kudo (app, GS_APP_KUDO_RECENT_RELEASE); /* add kudos */ if (as_app_get_language (item, plugin->locale) > 50) gs_app_add_kudo (app, GS_APP_KUDO_MY_LANGUAGE); /* add new-style kudos */ kudos = as_app_get_kudos (item); for (i = 0; i < kudos->len; i++) { tmp = g_ptr_array_index (kudos, i); switch (as_kudo_kind_from_string (tmp)) { case AS_KUDO_KIND_SEARCH_PROVIDER: gs_app_add_kudo (app, GS_APP_KUDO_SEARCH_PROVIDER); break; case AS_KUDO_KIND_USER_DOCS: gs_app_add_kudo (app, GS_APP_KUDO_INSTALLS_USER_DOCS); break; case AS_KUDO_KIND_APP_MENU: gs_app_add_kudo (app, GS_APP_KUDO_USES_APP_MENU); break; case AS_KUDO_KIND_MODERN_TOOLKIT: gs_app_add_kudo (app, GS_APP_KUDO_MODERN_TOOLKIT); break; case AS_KUDO_KIND_NOTIFICATIONS: gs_app_add_kudo (app, GS_APP_KUDO_USES_NOTIFICATIONS); break; case AS_KUDO_KIND_HIGH_CONTRAST: gs_app_add_kudo (app, GS_APP_KUDO_HIGH_CONTRAST); break; case AS_KUDO_KIND_HI_DPI_ICON: gs_app_add_kudo (app, GS_APP_KUDO_HI_DPI_ICON); break; default: g_debug ("no idea how to handle kudo '%s'", tmp); break; } } /* is there any update information */ rel = as_app_get_release_default (item); if (rel != NULL) { tmp = as_release_get_description (rel, NULL); if (tmp != NULL) { g_autofree gchar *desc = NULL; desc = as_markup_convert (tmp, AS_MARKUP_CONVERT_FORMAT_MARKDOWN, error); if (desc == NULL) return FALSE; gs_app_set_update_details (app, desc); } gs_app_set_update_urgency (app, as_release_get_urgency (rel)); gs_app_set_update_version (app, as_release_get_version (rel)); } return TRUE; }