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; }
/** * 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: */ gboolean gs_plugin_refine (GsPlugin *plugin, GList **list, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { GList *l; GsApp *app; g_autoptr(AsProfileTask) ptask = NULL; ptask = as_profile_start_literal (plugin->profile, "limba::refine"); for (l = *list; l != NULL; l = l->next) { app = GS_APP (l->data); /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), "Limba") != 0) continue; if (!gs_plugin_refine_app (plugin, app, error)) return FALSE; } /* sucess */ return TRUE; }
gboolean gs_plugin_launch (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { const gchar *launch_name; g_autofree gchar *binary_name = NULL; GAppInfoCreateFlags flags = G_APP_INFO_CREATE_NONE; g_autoptr(GAppInfo) info = NULL; /* We can only launch apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; launch_name = gs_app_get_metadata_item (app, "snap::launch-name"); if (!launch_name) return TRUE; if (g_strcmp0 (launch_name, gs_app_get_id (app)) == 0) binary_name = g_strdup_printf ("/snap/bin/%s", launch_name); else binary_name = g_strdup_printf ("/snap/bin/%s.%s", gs_app_get_id (app), launch_name); if (!is_graphical (app, cancellable)) flags |= G_APP_INFO_CREATE_NEEDS_TERMINAL; info = g_app_info_create_from_commandline (binary_name, NULL, flags, error); if (info == NULL) return FALSE; return g_app_info_launch (info, NULL, NULL, error); }
/** * 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_launch: */ gboolean gs_plugin_launch (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); const gchar *branch = 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; branch = gs_app_get_xdgapp_branch (app); if (branch == NULL) branch = "master"; return xdg_app_installation_launch (priv->installation, gs_app_get_xdgapp_name (app), NULL, branch, NULL, cancellable, error); }
/** * 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; }
/** * gs_plugin_launch: */ gboolean gs_plugin_launch (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "Epiphany") != 0) return TRUE; return gs_plugin_app_launch (plugin, app, error); }
gboolean gs_plugin_update_cancel (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0) return TRUE; return pk_offline_cancel (NULL, 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_app_upgrade_trigger (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0) return TRUE; return pk_offline_trigger_upgrade (PK_OFFLINE_ACTION_REBOOT, cancellable, error); }
gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { /* 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; /* source -> remote */ return gs_plugin_fwupd_modify_source (plugin, app, FALSE, cancellable, error); }
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_xdg_app_refine_app: */ static gboolean gs_plugin_xdg_app_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { g_autoptr(AsProfileTask) ptask = 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; /* profile */ ptask = as_profile_start (gs_plugin_get_profile (plugin), "xdg-app::refine{%s}", gs_app_get_id (app)); /* AppStream sets the source to appname/arch/branch */ if (!gs_plugin_refine_item_metadata (plugin, app, cancellable, error)) return FALSE; /* check the installed state */ if (!gs_plugin_refine_item_state (plugin, app, cancellable, error)) return FALSE; /* version fallback */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION) { if (gs_app_get_version (app) == NULL) { const gchar *branch; branch = gs_app_get_xdgapp_branch (app); gs_app_set_version (app, branch); } } /* size */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE) { if (!gs_plugin_refine_item_size (plugin, app, cancellable, error)) return FALSE; } /* origin */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN) { if (!gs_plugin_refine_item_origin_ui (plugin, app, cancellable, error)) return FALSE; } return TRUE; }
/** * 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_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_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { /* 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; /* source -> remote */ if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE) { return gs_plugin_fwupd_modify_source (plugin, app, TRUE, cancellable, error); } /* firmware */ return gs_plugin_fwupd_install (plugin, app, cancellable, error); }
gboolean gs_plugin_launch (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 */ gameid = gs_app_get_metadata_item (app, "X-Steam-GameID"); cmdline = g_strdup_printf ("steam steam://run/%s", gameid); if (!g_spawn_command_line_sync (cmdline, NULL, NULL, NULL, error)) { gs_utils_error_convert_gio (error); return FALSE; } return TRUE; }
gboolean gs_plugin_launch (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { const gchar *launch_name; const gchar *launch_desktop; g_autoptr(GAppInfo) info = NULL; /* We can only launch apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; launch_name = gs_app_get_metadata_item (app, "snap::launch-name"); launch_desktop = gs_app_get_metadata_item (app, "snap::launch-desktop"); if (!launch_name) return TRUE; if (launch_desktop) { info = (GAppInfo *)g_desktop_app_info_new_from_filename (launch_desktop); } else { g_autofree gchar *commandline = NULL; GAppInfoCreateFlags flags = G_APP_INFO_CREATE_NONE; if (g_strcmp0 (launch_name, gs_app_get_metadata_item (app, "snap::name")) == 0) commandline = g_strdup_printf ("snap run %s", launch_name); else commandline = g_strdup_printf ("snap run %s.%s", gs_app_get_metadata_item (app, "snap::name"), launch_name); if (!is_graphical (plugin, app, cancellable)) flags |= G_APP_INFO_CREATE_NEEDS_TERMINAL; info = g_app_info_create_from_commandline (commandline, NULL, flags, error); } if (info == NULL) return FALSE; return g_app_info_launch (info, NULL, NULL, error); }
gboolean gs_plugin_update_app (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; /* locked devices need unlocking, rather than installing */ if (gs_fwupd_app_get_is_locked (app)) { const gchar *device_id; device_id = gs_fwupd_app_get_device_id (app); if (device_id == NULL) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "not enough data for fwupd unlock"); return FALSE; } if (!fwupd_client_unlock (priv->client, device_id, cancellable, error)) { gs_plugin_fwupd_error_convert (error); return FALSE; } return TRUE; } /* update means install */ if (!gs_plugin_fwupd_install (plugin, app, cancellable, error)) { gs_plugin_fwupd_error_convert (error); return FALSE; } 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; }
gboolean gs_plugin_download_app (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GFile *local_file; g_autofree gchar *filename = 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; /* 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); if (!gs_plugin_download_file (plugin, app, uri, filename, cancellable, error)) return FALSE; } gs_app_set_size_download (app, 0); return TRUE; }
gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { g_autofree gchar *macaroon = NULL; g_auto(GStrv) discharges = NULL; g_autoptr(JsonObject) result = NULL; /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; get_macaroon (plugin, &macaroon, &discharges); result = gs_snapd_list_one (macaroon, discharges, gs_app_get_id (app), cancellable, error); if (result == NULL) return FALSE; refine_app (plugin, app, result, FALSE, cancellable); return TRUE; }
gboolean gs_plugin_update_app (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { /* if we can process this online do not require a trigger */ if (gs_app_get_state (app) != AS_APP_STATE_UPDATABLE) return TRUE; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0) return TRUE; /* trigger offline update */ if (!pk_offline_trigger (PK_OFFLINE_ACTION_REBOOT, cancellable, error)) { gs_plugin_packagekit_error_convert (error); return FALSE; } /* success! */ return TRUE; }
/** * gs_plugin_app_install: */ gboolean gs_plugin_app_install (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; /* ensure we have metadata and state */ if (!gs_plugin_xdg_app_refine_app (plugin, app, 0, cancellable, error)) return FALSE; /* install */ gs_app_set_state (app, AS_APP_STATE_INSTALLING); /* install required runtime if not already installed */ if (gs_app_get_kind (app) == AS_APP_KIND_DESKTOP) { GsApp *runtime; runtime = gs_app_get_runtime (app); /* the runtime could come from a different remote to the app */ if (!gs_plugin_refine_item_metadata (plugin, runtime, cancellable, error)) return FALSE; if (!gs_plugin_refine_item_origin (plugin, runtime, cancellable, error)) return FALSE; if (!gs_plugin_refine_item_state (plugin, runtime, cancellable, error)) return FALSE; if (gs_app_get_state (runtime) == AS_APP_STATE_UNKNOWN) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "Failed to find runtime %s", gs_app_get_source_default (runtime)); return FALSE; } /* not installed */ if (gs_app_get_state (runtime) == AS_APP_STATE_AVAILABLE) { g_debug ("%s is not already installed, so installing", gs_app_get_id (runtime)); gs_app_set_state (runtime, AS_APP_STATE_INSTALLING); xref = xdg_app_installation_install (priv->installation, gs_app_get_origin (runtime), gs_app_get_xdgapp_kind (runtime), gs_app_get_xdgapp_name (runtime), gs_app_get_xdgapp_arch (runtime), gs_app_get_xdgapp_branch (runtime), gs_plugin_xdg_app_progress_cb, app, cancellable, error); if (xref == NULL) { gs_app_set_state_recover (runtime); return FALSE; } gs_app_set_state (runtime, AS_APP_STATE_INSTALLED); } else { g_debug ("%s is already installed, so skipping", gs_app_get_id (runtime)); } } /* use the source for local apps */ if (gs_app_get_state (app) == AS_APP_STATE_AVAILABLE_LOCAL) { xref = xdg_app_installation_install_bundle (priv->installation, gs_app_get_local_file (app), gs_plugin_xdg_app_progress_cb, app, cancellable, error); } else { g_debug ("installing %s", gs_app_get_id (app)); xref = xdg_app_installation_install (priv->installation, gs_app_get_origin (app), 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; }
/** * gs_plugin_app_update: * * Used only for online-updates. */ gboolean gs_plugin_app_update (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginHelper helper; g_autoptr(LiManager) mgr = NULL; LiUpdateItem *uitem; g_autoptr(GError) error_local = NULL; /* check if this update request is for us */ if (g_strcmp0 (gs_app_get_management_plugin (app), "Limba") != 0) return TRUE; /* sanity check */ if (gs_app_get_source_default (app) == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to run update: Default source was NULL."); return FALSE; } 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); /* find update which matches the ID we have */ uitem = li_manager_get_update_for_id (mgr, 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 find update: %s", error_local->message); return FALSE; } if (uitem == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Could not find update for '%s'.", gs_app_get_source_default (app)); return FALSE; } gs_app_set_state (app, AS_APP_STATE_INSTALLING); li_manager_update (mgr, uitem, &error_local); if (error_local != NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Software update failed: %s", error_local->message); gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); 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); g_autoptr(SnapdClient) client = NULL; const gchar *name; g_autoptr(SnapdSnap) local_snap = NULL; g_autoptr(SnapdSnap) store_snap = NULL; SnapdSnap *snap; const gchar *developer_name; g_autofree gchar *description = NULL; /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; client = get_client (plugin, error); if (client == NULL) return FALSE; /* get information from local snaps and store */ local_snap = snapd_client_get_snap_sync (client, gs_app_get_metadata_item (app, "snap::name"), cancellable, NULL); if (local_snap == NULL || (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SCREENSHOTS) != 0) store_snap = get_store_snap (plugin, gs_app_get_metadata_item (app, "snap::name"), cancellable, NULL); if (local_snap == NULL && store_snap == NULL) return TRUE; if (local_snap != NULL) gs_app_set_state (app, AS_APP_STATE_INSTALLED); else gs_app_set_state (app, AS_APP_STATE_AVAILABLE); /* use store information for basic metadata over local information */ snap = store_snap != NULL ? store_snap : local_snap; name = snapd_snap_get_title (snap); if (name == NULL || g_strcmp0 (name, "") == 0) name = snapd_snap_get_name (snap); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, name); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, snapd_snap_get_summary (snap)); description = gs_plugin_snap_get_description_safe (snap); if (description != NULL) gs_app_set_description (app, GS_APP_QUALITY_NORMAL, description); gs_app_set_license (app, GS_APP_QUALITY_NORMAL, snapd_snap_get_license (snap)); developer_name = snapd_snap_get_publisher_display_name (snap); if (developer_name == NULL) developer_name = snapd_snap_get_publisher_username (snap); gs_app_set_developer_name (app, developer_name); if (snapd_snap_get_publisher_validation (snap) == SNAPD_PUBLISHER_VALIDATION_VERIFIED) gs_app_add_quirk (app, GS_APP_QUIRK_DEVELOPER_VERIFIED); snap = local_snap != NULL ? local_snap : store_snap; gs_app_set_version (app, snapd_snap_get_version (snap)); switch (snapd_snap_get_snap_type (snap)) { case SNAPD_SNAP_TYPE_APP: gs_app_set_kind (app, AS_APP_KIND_DESKTOP); break; case SNAPD_SNAP_TYPE_KERNEL: case SNAPD_SNAP_TYPE_GADGET: case SNAPD_SNAP_TYPE_OS: gs_app_set_kind (app, AS_APP_KIND_RUNTIME); break; default: case SNAPD_SNAP_TYPE_UNKNOWN: gs_app_set_kind (app, AS_APP_KIND_UNKNOWN); break; } /* add information specific to installed snaps */ if (local_snap != NULL) { SnapdApp *snap_app; GDateTime *install_date; install_date = snapd_snap_get_install_date (local_snap); gs_app_set_size_installed (app, snapd_snap_get_installed_size (local_snap)); gs_app_set_install_date (app, install_date != NULL ? g_date_time_to_unix (install_date) : GS_APP_INSTALL_DATE_UNKNOWN); snap_app = get_primary_app (local_snap); if (snap_app != NULL) { gs_app_set_metadata (app, "snap::launch-name", snapd_app_get_name (snap_app)); gs_app_set_metadata (app, "snap::launch-desktop", snapd_app_get_desktop_file (snap_app)); } else { gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE); } } /* add information specific to store snaps */ if (store_snap != NULL) { gs_app_set_origin (app, priv->store_name); gs_app_set_size_download (app, snapd_snap_get_download_size (store_snap)); if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SCREENSHOTS && gs_app_get_screenshots (app)->len == 0) refine_screenshots (app, store_snap); } /* load icon if requested */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON && gs_app_get_pixbuf (app) == NULL) load_icon (plugin, client, app, gs_app_get_metadata_item (app, "snap::name"), local_snap, store_snap, cancellable); return TRUE; }
gboolean gs_plugin_app_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); GPtrArray *addons; GPtrArray *source_ids; ProgressData data; const gchar *package_id; guint i, j; g_autofree gchar *local_filename = NULL; g_auto(GStrv) package_ids = NULL; g_autoptr(GPtrArray) array_package_ids = NULL; g_autoptr(PkResults) results = NULL; data.app = app; data.plugin = plugin; data.ptask = 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; /* we enable the repo */ if (gs_app_get_state (app) == AS_APP_STATE_UNAVAILABLE) { /* get everything up front we need */ source_ids = gs_app_get_source_ids (app); if (source_ids->len == 0) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "installing not available"); return FALSE; } package_ids = g_new0 (gchar *, 2); package_ids[0] = g_strdup (g_ptr_array_index (source_ids, 0)); /* enable the source */ if (!gs_plugin_app_source_enable (plugin, app, cancellable, error)) return FALSE; /* FIXME: this is a hack, to allow PK time to re-initialize * everything in order to match an actual result. The root cause * is probably some kind of hard-to-debug race in the daemon. */ g_usleep (G_USEC_PER_SEC * 3); /* actually install the package */ gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_state (app, AS_APP_STATE_INSTALLING); results = pk_task_install_packages_sync (priv->task, package_ids, 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_INSTALLED); /* no longer valid */ gs_app_clear_source_ids (app); return TRUE; }