Commit c77ea510 authored by Patrick Griffis's avatar Patrick Griffis 💬
Browse files

Remove Google Cloud Print backend

This service was shut down at the start of 2021
parent 3e1214bd
Pipeline #294683 passed with stages
in 44 minutes and 22 seconds
......@@ -15,7 +15,7 @@ meson \
-Dx11_backend=true \
-Dwayland_backend=true \
-Dxinerama=yes \
-Dprint_backends="file,lpr,test,cloudprint,cups" \
-Dprint_backends="file,lpr,test,cups" \
${EXTRA_MESON_FLAGS:-} \
_build
......
......@@ -1576,38 +1576,6 @@ fi
AM_CONDITIONAL(HAVE_TRACKER3, test "x$have_tracker3" = "xyes")
# Checks to see if we should compile with cloudprint backend for GTK+
#
AC_ARG_ENABLE(cloudprint,
[AS_HELP_STRING([--disable-cloudprint],
[disable cloudprint print backend])],,
[enable_cloudprint=auto])
if test "x$enable_cloudprint" = "xno"; then
AM_CONDITIONAL(HAVE_CLOUDPRINT, false)
else
PKG_CHECK_MODULES(REST, [rest-0.7], have_rest=yes, have_rest=no)
PKG_CHECK_MODULES(JSON_GLIB, [json-glib-1.0], have_json_glib=yes, have_json_glib=no)
if test "x$have_rest" = "xyes" -a "x$have_json_glib" = "xyes"; then
PRINT_BACKENDS="$PRINT_BACKENDS cloudprint"
have_cloudprint=yes
fi
AM_CONDITIONAL(HAVE_CLOUDPRINT, test "x$have_cloudprint" = "xyes")
fi
if test "x$enable_cloudprint" = "xyes" -a "x$have_rest" = "xno"; then
AC_MSG_ERROR([
*** rest not found.
])
fi
if test "x$enable_cloudprint" = "xyes" -a "x$have_json_glib" = "xno"; then
AC_MSG_ERROR([
*** json-glib not found.
])
fi
gtk_save_cppflags="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $GTK_DEP_CFLAGS $GDK_DEP_CFLAGS"
......@@ -1650,9 +1618,6 @@ fi
if test "$have_papi" != "yes" -a "$have_cups" != "yes"; then
GTK_PRINT_BACKENDS="$GTK_PRINT_BACKENDS,lpr"
fi
if test "$have_cloudprint" = "yes"; then
GTK_PRINT_BACKENDS="$GTK_PRINT_BACKENDS,cloudprint"
fi
AC_SUBST(GTK_PRINT_BACKENDS)
################################################################
......@@ -1994,7 +1959,6 @@ modules/Makefile
modules/input/Makefile
modules/printbackends/Makefile
modules/printbackends/cups/Makefile
modules/printbackends/cloudprint/Makefile
modules/printbackends/lpr/Makefile
modules/printbackends/file/Makefile
modules/printbackends/papi/Makefile
......
......@@ -22,7 +22,7 @@ option('tracker3', type: 'boolean', value: false,
# Print backends
option('print_backends', type : 'string', value : 'auto',
description : 'Build the specified print backends (comma-separated list, any of "cloudprint,cups,file,lpr,papi,test" or "auto")')
description : 'Build the specified print backends (comma-separated list, any of "cups,file,lpr,papi,test" or "auto")')
option('colord', type: 'combo', choices : ['yes', 'no', 'auto'], value : 'auto',
description : 'Build colord support for the CUPS printing backend')
......
......@@ -2,10 +2,6 @@ include $(top_srcdir)/Makefile.decl
SUBDIRS = file lpr
if HAVE_CLOUDPRINT
SUBDIRS += cloudprint
endif
if HAVE_CUPS
SUBDIRS += cups
endif
......@@ -18,7 +14,7 @@ if HAVE_PAPI
SUBDIRS += papi
endif
DIST_SUBDIRS = cloudprint cups file lpr test papi
DIST_SUBDIRS = cups file lpr test papi
EXTRA_DIST += \
meson.build
......
include $(top_srcdir)/Makefile.decl
backenddir = $(libdir)/gtk-3.0/$(GTK_BINARY_VERSION)/printbackends
backend_LTLIBRARIES = libprintbackend-cloudprint.la
libprintbackend_cloudprint_la_SOURCES = \
gtkprintbackendcloudprint.h \
gtkprintbackendcloudprint.c \
gtkprintercloudprint.h \
gtkprintercloudprint.c \
gtkcloudprintaccount.h \
gtkcloudprintaccount.c
libprintbackend_cloudprint_la_CPPFLAGS = \
-I$(top_srcdir) \
-I$(top_srcdir)/gtk \
-I$(top_builddir)/gtk \
-I$(top_srcdir)/gdk \
-I$(top_builddir)/gdk \
-DGTK_PRINT_BACKEND_ENABLE_UNSUPPORTED \
$(AM_CPPFLAGS)
libprintbackend_cloudprint_la_CFLAGS = \
$(GTK_DEP_CFLAGS) \
$(GTK_DEBUG_FLAGS) \
$(REST_CFLAGS) \
$(JSON_GLIB_CFLAGS) \
$(AM_CFLAGS)
libprintbackend_cloudprint_la_LDFLAGS = \
-avoid-version -module $(no_undefined)
libprintbackend_cloudprint_la_LIBADD = \
$(top_builddir)/gtk/libgtk-3.la \
$(REST_LIBS) \
$(JSON_GLIB_LIBS) \
$(GTK_DEP_LIBS)
-include $(top_srcdir)/git.mk
/* gtkcloudprintaccount.c: Google Cloud Print account class
* Copyright (C) 2014, Red Hat, Inc.
*
* 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 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, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <rest/oauth2-proxy.h>
#include <rest/rest-proxy.h>
#include <rest/rest-proxy-call.h>
#include <json-glib/json-glib.h>
#include <gtk/gtkunixprint.h>
#include "gtkcloudprintaccount.h"
#include "gtkprintercloudprint.h"
#define CLOUDPRINT_PROXY "GTK+"
#define ACCOUNT_IFACE "org.gnome.OnlineAccounts.Account"
#define O_AUTH2_BASED_IFACE "org.gnome.OnlineAccounts.OAuth2Based"
#define GTK_CLOUDPRINT_ACCOUNT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CLOUDPRINT_ACCOUNT, GtkCloudprintAccountClass))
#define GTK_IS_CLOUDPRINT_ACCOUNT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CLOUDPRINT_ACCOUNT))
#define GTK_CLOUDPRINT_ACCOUNT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CLOUDPRINT_ACCOUNT, GtkCloudprintAccountClass))
static GObjectClass *gtk_cloudprint_account_parent_class;
static GType gtk_cloudprint_account_type = 0;
typedef struct _GtkCloudprintAccountClass GtkCloudprintAccountClass;
struct _GtkCloudprintAccountClass
{
GObjectClass parent_class;
};
struct _GtkCloudprintAccount
{
GObject parent_instance;
gchar *printer_id;
gchar *goa_path;
gchar *presentation_identity;
RestProxy *rest_proxy;
gchar *oauth2_access_token;
};
static void gtk_cloudprint_account_class_init (GtkCloudprintAccountClass *class);
static void gtk_cloudprint_account_init (GtkCloudprintAccount *impl);
static void gtk_cloudprint_account_finalize (GObject *object);
void
gtk_cloudprint_account_register_type (GTypeModule *module)
{
const GTypeInfo cloudprint_account_info =
{
sizeof (GtkCloudprintAccountClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_cloudprint_account_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkCloudprintAccount),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_cloudprint_account_init,
};
gtk_cloudprint_account_type = g_type_module_register_type (module,
G_TYPE_OBJECT,
"GtkCloudprintAccount",
&cloudprint_account_info, 0);
}
/*
* GtkCloudprintAccount
*/
GType
gtk_cloudprint_account_get_type (void)
{
return gtk_cloudprint_account_type;
}
/**
* gtk_cloudprint_account_new:
*
* Creates a new #GtkCloudprintAccount object, representing a Google
* Cloud Print account and its state data.
*
* Returns: the new #GtkCloudprintAccount object
**/
GtkCloudprintAccount *
gtk_cloudprint_account_new (const gchar *id,
const gchar *path,
const gchar *presentation_identity)
{
GtkCloudprintAccount *account = g_object_new (GTK_TYPE_CLOUDPRINT_ACCOUNT,
NULL);
account->printer_id = g_strdup (id);
account->goa_path = g_strdup (path);
account->presentation_identity = g_strdup (presentation_identity);
return account;
}
static void
gtk_cloudprint_account_class_init (GtkCloudprintAccountClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gtk_cloudprint_account_parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize = gtk_cloudprint_account_finalize;
}
static void
gtk_cloudprint_account_init (GtkCloudprintAccount *account)
{
account->printer_id = NULL;
account->goa_path = NULL;
account->presentation_identity = NULL;
account->rest_proxy = NULL;
account->oauth2_access_token = NULL;
GTK_NOTE (PRINTING,
g_print ("Cloud Print Backend: +GtkCloudprintAccount(%p)\n",
account));
}
static void
gtk_cloudprint_account_finalize (GObject *object)
{
GtkCloudprintAccount *account;
account = GTK_CLOUDPRINT_ACCOUNT (object);
GTK_NOTE (PRINTING,
g_print ("Cloud Print Backend: -GtkCloudprintAccount(%p)\n",
account));
g_clear_object (&(account->rest_proxy));
g_clear_pointer (&(account->printer_id), g_free);
g_clear_pointer (&(account->goa_path), g_free);
g_clear_pointer (&(account->presentation_identity), g_free);
g_clear_pointer (&(account->oauth2_access_token), g_free);
G_OBJECT_CLASS (gtk_cloudprint_account_parent_class)->finalize (object);
}
static JsonParser *
cloudprint_json_parse (RestProxyCall *call, JsonObject **result, GError **error)
{
JsonParser *json_parser = json_parser_new ();
JsonNode *root;
JsonObject *json_object;
gboolean success = FALSE;
if (!json_parser_load_from_data (json_parser,
rest_proxy_call_get_payload (call),
rest_proxy_call_get_payload_length (call),
error))
{
g_object_unref (json_parser);
return NULL;
}
root = json_parser_get_root (json_parser);
if (JSON_NODE_TYPE (root) != JSON_NODE_OBJECT)
{
if (error != NULL)
*error = g_error_new_literal (gtk_print_error_quark (),
GTK_PRINT_ERROR_INTERNAL_ERROR,
"Bad reply");
g_object_unref (json_parser);
return NULL;
}
json_object = json_node_get_object (root);
if (json_object_has_member (json_object, "success"))
success = json_object_get_boolean_member (json_object, "success");
if (!success)
{
const gchar *message = "(no message)";
if (json_object_has_member (json_object, "message"))
message = json_object_get_string_member (json_object, "message");
GTK_NOTE (PRINTING,
g_print ("Cloud Print Backend: unsuccessful submit: %s\n",
message));
if (error != NULL)
*error = g_error_new_literal (gtk_print_error_quark (),
GTK_PRINT_ERROR_INTERNAL_ERROR,
message);
g_object_unref (json_parser);
return NULL;
}
if (result != NULL)
*result = json_node_dup_object (root);
return json_parser;
}
static void
gtk_cloudprint_account_search_rest_call_cb (RestProxyCall *call,
const GError *cb_error,
GObject *weak_object,
gpointer user_data)
{
GTask *task = user_data;
JsonParser *json_parser = NULL;
JsonObject *result;
JsonNode *printers = NULL;
GError *error = NULL;
#ifdef G_ENABLE_DEBUG
{
GtkCloudprintAccount *account = g_task_get_task_data (task);
GTK_NOTE (PRINTING,
g_print ("Cloud Print Backend: (%p) 'search' REST call returned\n",
account));
}
#endif
if (cb_error != NULL)
{
error = g_error_copy (cb_error);
g_task_return_error (task, error);
g_object_unref (task);
return;
}
if (g_task_return_error_if_cancelled (task))
{
g_object_unref (task);
return;
}
if ((json_parser = cloudprint_json_parse (call, &result, &error)) == NULL)
{
g_task_return_error (task, error);
g_object_unref (task);
return;
}
g_object_unref (json_parser);
if (json_object_has_member (result, "printers"))
printers = json_object_dup_member (result, "printers");
json_object_unref (result);
if (printers == NULL)
{
g_task_return_new_error (task,
gtk_print_error_quark (),
GTK_PRINT_ERROR_INTERNAL_ERROR,
"Bad reply to 'search' request");
return;
}
g_task_return_pointer (task,
printers,
(GDestroyNotify) json_node_free);
g_object_unref (task);
}
static void
gtk_cloudprint_account_got_oauth2_access_token_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GTask *task = user_data;
GtkCloudprintAccount *account = g_task_get_task_data (task);
RestProxyCall *call;
RestProxy *rest;
GVariant *output;
gint expires_in = 0;
GError *error = NULL;
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
result,
&error);
g_object_unref (source);
if (output == NULL)
{
g_task_return_error (task, error);
g_object_unref (task);
return;
}
g_variant_get (output, "(si)",
&account->oauth2_access_token,
&expires_in);
g_variant_unref (output);
rest = oauth2_proxy_new_with_token (account->printer_id,
account->oauth2_access_token,
"https://accounts.google.com/o/oauth2/token",
"https://www.google.com/cloudprint/",
FALSE);
if (rest == NULL)
{
g_task_return_new_error (task,
gtk_print_error_quark (),
GTK_PRINT_ERROR_INTERNAL_ERROR,
"REST proxy creation failed");
g_object_unref (task);
return;
}
GTK_NOTE (PRINTING,
g_print ("Cloud Print Backend: (%p) 'search' REST call\n",
account));
account->rest_proxy = g_object_ref (rest);
call = rest_proxy_new_call (REST_PROXY (rest));
g_object_unref (rest);
rest_proxy_call_set_function (call, "search");
rest_proxy_call_add_header (call, "X-CloudPrint-Proxy", CLOUDPRINT_PROXY);
rest_proxy_call_add_param (call, "connection_status", "ALL");
if (!rest_proxy_call_async (call,
gtk_cloudprint_account_search_rest_call_cb,
NULL,
task,
&error))
{
g_task_return_error (task, error);
g_object_unref (task);
}
g_object_unref (call);
}
static void
gtk_cloudprint_account_ensure_credentials_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GTask *task = user_data;
GtkCloudprintAccount *account = g_task_get_task_data (task);
GVariant *output;
gint expires_in = 0;
GError *error = NULL;
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source),
result,
&error);
if (output == NULL)
{
g_object_unref (source);
if (error->domain != G_DBUS_ERROR ||
(error->code != G_DBUS_ERROR_SERVICE_UNKNOWN &&
error->code != G_DBUS_ERROR_UNKNOWN_METHOD))
g_task_return_error (task, error);
else
/* Return an empty list. */
g_task_return_pointer (task,
json_node_new (JSON_NODE_ARRAY),
(GDestroyNotify) json_node_free);
g_object_unref (task);
return;
}
g_variant_get (output, "(i)",
&expires_in);
g_variant_unref (output);
GTK_NOTE (PRINTING,
g_print ("Cloud Print Backend: (%p) getting access token\n",
account));
g_dbus_connection_call (G_DBUS_CONNECTION (source),
ONLINE_ACCOUNTS_BUS,
account->goa_path,
O_AUTH2_BASED_IFACE,
"GetAccessToken",
NULL,
G_VARIANT_TYPE ("(si)"),
G_DBUS_CALL_FLAGS_NONE,
-1,
g_task_get_cancellable (task),
gtk_cloudprint_account_got_oauth2_access_token_cb,
task);
}
void
gtk_cloudprint_account_search (GtkCloudprintAccount *account,
GDBusConnection *dbus_connection,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task = g_task_new (G_OBJECT (account),
cancellable,
callback,
user_data);
g_task_set_task_data (task,
g_object_ref (account),
(GDestroyNotify) g_object_unref);
GTK_NOTE (PRINTING,
g_print ("Cloud Print Backend: (%p) ensuring credentials\n",
account));
g_dbus_connection_call (g_object_ref (dbus_connection),
ONLINE_ACCOUNTS_BUS,
account->goa_path,
ACCOUNT_IFACE,
"EnsureCredentials",
NULL,
G_VARIANT_TYPE ("(i)"),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
gtk_cloudprint_account_ensure_credentials_cb,
task);
}
JsonNode *
gtk_cloudprint_account_search_finish (GtkCloudprintAccount *account,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (g_task_is_valid (result, account), NULL);
return g_task_propagate_pointer (G_TASK (result), error);
}
static void
gtk_cloudprint_account_printer_rest_call_cb (RestProxyCall *call,
const GError *cb_error,
GObject *weak_object,
gpointer user_data)
{
GTask *task = user_data;
JsonParser *json_parser = NULL;
JsonObject *result;
GError *error = NULL;
#ifdef G_ENABLE_DEBUG
{
GtkCloudprintAccount *account = g_task_get_task_data (task);
GTK_NOTE (PRINTING,
g_print ("Cloud Print Backend: (%p) 'printer' REST call returned\n",
account));
}
#endif
if (cb_error != NULL)
{
error = g_error_copy (cb_error);
g_task_return_error (task, error);
g_object_unref (task);
return;
}