Commit 4340b4c1 authored by Robert Ancell's avatar Robert Ancell Committed by Kalev Lember

Allow purchase failures to be handled

GNOME/gnome-software!28
parent 732951db
...@@ -409,6 +409,12 @@ gs_plugin_loader_is_error_fatal (GsPluginFailureFlags failure_flags, ...@@ -409,6 +409,12 @@ gs_plugin_loader_is_error_fatal (GsPluginFailureFlags failure_flags,
if (g_error_matches (err, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_AUTH_INVALID)) if (g_error_matches (err, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_AUTH_INVALID))
return TRUE; return TRUE;
} }
if (failure_flags & GS_PLUGIN_FAILURE_FLAGS_FATAL_PURCHASE) {
if (g_error_matches (err, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_PURCHASE_NOT_SETUP))
return TRUE;
if (g_error_matches (err, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_PURCHASE_DECLINED))
return TRUE;
}
if (g_error_matches (err, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_TIMED_OUT)) if (g_error_matches (err, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_TIMED_OUT))
return TRUE; return TRUE;
return FALSE; return FALSE;
......
...@@ -92,6 +92,8 @@ typedef guint64 GsPluginFlags; ...@@ -92,6 +92,8 @@ typedef guint64 GsPluginFlags;
* @GS_PLUGIN_ERROR_RESTART_REQUIRED: A restart is required * @GS_PLUGIN_ERROR_RESTART_REQUIRED: A restart is required
* @GS_PLUGIN_ERROR_AC_POWER_REQUIRED: AC power is required * @GS_PLUGIN_ERROR_AC_POWER_REQUIRED: AC power is required
* @GS_PLUGIN_ERROR_TIMED_OUT: The job timed out * @GS_PLUGIN_ERROR_TIMED_OUT: The job timed out
* @GS_PLUGIN_ERROR_PURCHASE_NOT_SETUP: Purchase support not setup
* @GS_PLUGIN_ERROR_PURCHASE_DECLINED: Purchase was declined
* *
* The failure error types. * The failure error types.
**/ **/
...@@ -115,6 +117,8 @@ typedef enum { ...@@ -115,6 +117,8 @@ typedef enum {
GS_PLUGIN_ERROR_RESTART_REQUIRED, GS_PLUGIN_ERROR_RESTART_REQUIRED,
GS_PLUGIN_ERROR_AC_POWER_REQUIRED, GS_PLUGIN_ERROR_AC_POWER_REQUIRED,
GS_PLUGIN_ERROR_TIMED_OUT, GS_PLUGIN_ERROR_TIMED_OUT,
GS_PLUGIN_ERROR_PURCHASE_NOT_SETUP,
GS_PLUGIN_ERROR_PURCHASE_DECLINED,
/*< private >*/ /*< private >*/
GS_PLUGIN_ERROR_LAST GS_PLUGIN_ERROR_LAST
} GsPluginError; } GsPluginError;
...@@ -325,6 +329,7 @@ typedef enum { ...@@ -325,6 +329,7 @@ typedef enum {
* @GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY: Abort after any plugin error * @GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY: Abort after any plugin error
* @GS_PLUGIN_FAILURE_FLAGS_FATAL_AUTH: Abort after a authentication error * @GS_PLUGIN_FAILURE_FLAGS_FATAL_AUTH: Abort after a authentication error
* @GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE: Do not show a message on the console * @GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE: Do not show a message on the console
* @GS_PLUGIN_FAILURE_FLAGS_FATAL_PURCHASE: Abort after a purchase error
* *
* The failure flags for the plugin action. * The failure flags for the plugin action.
* *
...@@ -337,6 +342,7 @@ typedef enum { ...@@ -337,6 +342,7 @@ typedef enum {
#define GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY ((guint64) 1 << 1) #define GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY ((guint64) 1 << 1)
#define GS_PLUGIN_FAILURE_FLAGS_FATAL_AUTH ((guint64) 1 << 2) #define GS_PLUGIN_FAILURE_FLAGS_FATAL_AUTH ((guint64) 1 << 2)
#define GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE ((guint64) 1 << 3) #define GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE ((guint64) 1 << 3)
#define GS_PLUGIN_FAILURE_FLAGS_FATAL_PURCHASE ((guint64) 1 << 4)
typedef guint64 GsPluginFailureFlags; typedef guint64 GsPluginFailureFlags;
G_END_DECLS G_END_DECLS
......
...@@ -1667,6 +1667,10 @@ gs_plugin_error_to_string (GsPluginError error) ...@@ -1667,6 +1667,10 @@ gs_plugin_error_to_string (GsPluginError error)
return "ac-power-required"; return "ac-power-required";
if (error == GS_PLUGIN_ERROR_TIMED_OUT) if (error == GS_PLUGIN_ERROR_TIMED_OUT)
return "timed-out"; return "timed-out";
if (error == GS_PLUGIN_ERROR_PURCHASE_NOT_SETUP)
return "purchase-not-setup";
if (error == GS_PLUGIN_ERROR_PURCHASE_DECLINED)
return "purchase-declined";
return NULL; return NULL;
} }
...@@ -1988,6 +1992,8 @@ gs_plugin_failure_flags_to_string (GsPluginFailureFlags failure_flags) ...@@ -1988,6 +1992,8 @@ gs_plugin_failure_flags_to_string (GsPluginFailureFlags failure_flags)
g_ptr_array_add (cstrs, "fatal-auth"); g_ptr_array_add (cstrs, "fatal-auth");
if (failure_flags & GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE) if (failure_flags & GS_PLUGIN_FAILURE_FLAGS_NO_CONSOLE)
g_ptr_array_add (cstrs, "no-console"); g_ptr_array_add (cstrs, "no-console");
if (failure_flags & GS_PLUGIN_FAILURE_FLAGS_FATAL_PURCHASE)
g_ptr_array_add (cstrs, "fatal-purchase");
if (cstrs->len == 0) if (cstrs->len == 0)
return g_strdup ("none"); return g_strdup ("none");
g_ptr_array_add (cstrs, NULL); g_ptr_array_add (cstrs, NULL);
......
...@@ -328,7 +328,8 @@ gs_page_purchase_authenticate_cb (GsPage *page, ...@@ -328,7 +328,8 @@ gs_page_purchase_authenticate_cb (GsPage *page,
plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_PURCHASE, plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_PURCHASE,
"app", helper->app, "app", helper->app,
"price", gs_app_get_price (helper->app), "price", gs_app_get_price (helper->app),
"failure-flags", GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS, "failure-flags", GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS |
GS_PLUGIN_FAILURE_FLAGS_FATAL_PURCHASE,
NULL); NULL);
gs_plugin_loader_job_process_async (priv->plugin_loader, plugin_job, gs_plugin_loader_job_process_async (priv->plugin_loader, plugin_job,
helper->cancellable, helper->cancellable,
...@@ -372,6 +373,25 @@ gs_page_app_purchased_cb (GObject *source, ...@@ -372,6 +373,25 @@ gs_page_app_purchased_cb (GObject *source,
helper); helper);
g_steal_pointer (&helper); g_steal_pointer (&helper);
return; return;
} else if (g_error_matches (error,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_PURCHASE_NOT_SETUP)) {
const gchar *url;
/* have we been given a link */
url = gs_utils_get_error_value (error);
if (url != NULL) {
g_autoptr(GError) error_local = NULL;
g_debug ("showing link in: %s", error->message);
if (!gtk_show_uri_on_window (GTK_WINDOW (gs_shell_get_window (priv->shell)),
url,
GDK_CURRENT_TIME,
&error_local)) {
g_warning ("failed to show URI %s: %s",
url, error_local->message);
}
return;
}
} }
g_warning ("failed to purchase %s: %s", g_warning ("failed to purchase %s: %s",
...@@ -421,7 +441,8 @@ gs_page_install_purchase_response_cb (GtkDialog *dialog, ...@@ -421,7 +441,8 @@ gs_page_install_purchase_response_cb (GtkDialog *dialog,
"app", helper->app, "app", helper->app,
"price", gs_app_get_price (helper->app), "price", gs_app_get_price (helper->app),
"failure-flags", GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS | "failure-flags", GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS |
GS_PLUGIN_FAILURE_FLAGS_FATAL_AUTH, GS_PLUGIN_FAILURE_FLAGS_FATAL_AUTH |
GS_PLUGIN_FAILURE_FLAGS_FATAL_PURCHASE,
NULL); NULL);
gs_plugin_loader_job_process_async (priv->plugin_loader, gs_plugin_loader_job_process_async (priv->plugin_loader,
plugin_job, plugin_job,
......
...@@ -982,6 +982,66 @@ gs_shell_show_event_refresh (GsShell *shell, GsPluginEvent *event) ...@@ -982,6 +982,66 @@ gs_shell_show_event_refresh (GsShell *shell, GsPluginEvent *event)
return TRUE; return TRUE;
} }
static gboolean
gs_shell_show_event_purchase (GsShell *shell, GsPluginEvent *event)
{
GsApp *app = gs_plugin_event_get_app (event);
const GError *error = gs_plugin_event_get_error (event);
g_autofree gchar *str_app = NULL;
g_autoptr(GString) str = g_string_new (NULL);
str_app = gs_shell_get_title_from_app (app);
switch (error->code) {
case GS_PLUGIN_ERROR_AUTH_REQUIRED:
case GS_PLUGIN_ERROR_PIN_REQUIRED:
/* TRANSLATORS: failure text for the in-app notification,
* where the %s is the application name (e.g. "GIMP") */
g_string_append_printf (str, _("Unable to purchase %s: "
"authentication was required"),
str_app);
break;
case GS_PLUGIN_ERROR_AUTH_INVALID:
/* TRANSLATORS: failure text for the in-app notification,
* where the %s is the application name (e.g. "GIMP") */
g_string_append_printf (str, _("Unable to purchase %s: "
"authentication was invalid"),
str_app);
break;
case GS_PLUGIN_ERROR_PURCHASE_NOT_SETUP:
/* TRANSLATORS: failure text for the in-app notification,
* where the %s is the application name (e.g. "GIMP") */
g_string_append_printf (str, _("Unable to purchase %s: "
"no payment method setup"),
str_app);
break;
case GS_PLUGIN_ERROR_PURCHASE_DECLINED:
/* TRANSLATORS: failure text for the in-app notification,
* where the %s is the application name (e.g. "GIMP") */
g_string_append_printf (str, _("Unable to purchase %s: "
"payment was declined"),
str_app);
break;
default:
/* TRANSLATORS: failure text for the in-app notification,
* where the %s is the application name (e.g. "GIMP") */
g_string_append_printf (str, _("Unable to purchase %s"), str_app);
break;
}
if (str->len == 0)
return FALSE;
/* add extra debugging for debug builds */
if (gs_shell_show_detailed_error (shell, error)) {
g_autofree gchar *first_line = get_first_line (error->message);
if (first_line != NULL)
g_string_append_printf (str, ":\n%s", first_line);
}
/* show in-app notification */
gs_shell_show_event_app_notify (shell, str->str, GS_SHELL_EVENT_BUTTON_NONE);
return TRUE;
}
static gboolean static gboolean
gs_shell_show_event_install (GsShell *shell, GsPluginEvent *event) gs_shell_show_event_install (GsShell *shell, GsPluginEvent *event)
{ {
...@@ -1638,6 +1698,8 @@ gs_shell_show_event (GsShell *shell, GsPluginEvent *event) ...@@ -1638,6 +1698,8 @@ gs_shell_show_event (GsShell *shell, GsPluginEvent *event)
switch (action) { switch (action) {
case GS_PLUGIN_ACTION_REFRESH: case GS_PLUGIN_ACTION_REFRESH:
return gs_shell_show_event_refresh (shell, event); return gs_shell_show_event_refresh (shell, event);
case GS_PLUGIN_ACTION_PURCHASE:
return gs_shell_show_event_purchase (shell, event);
case GS_PLUGIN_ACTION_INSTALL: case GS_PLUGIN_ACTION_INSTALL:
return gs_shell_show_event_install (shell, event); return gs_shell_show_event_install (shell, event);
case GS_PLUGIN_ACTION_UPDATE: case GS_PLUGIN_ACTION_UPDATE:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment