aboutsummaryrefslogtreecommitdiff
path: root/src/application-service-appstore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/application-service-appstore.c')
-rw-r--r--src/application-service-appstore.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c
index 3e827d5..d2678fd 100644
--- a/src/application-service-appstore.c
+++ b/src/application-service-appstore.c
@@ -110,6 +110,7 @@ struct _Application {
gchar * guide;
gboolean currently_free;
guint ordering_index;
+ GList * approver_cancels;
GList * approved_by;
visible_state_t visible_state;
guint name_watcher;
@@ -498,7 +499,8 @@ got_all_properties (GObject * source_object, GAsyncResult * res,
if (menu == NULL || id == NULL || category == NULL || status == NULL ||
icon_name == NULL) {
g_warning("Notification Item on object %s of %s doesn't have enough properties.", app->dbus_object, app->dbus_name);
- g_free(app); // Need to do more than this, but it gives the idea of the flow we're going for.
+ if (!app->validated)
+ application_free(app);
}
else {
app->validated = TRUE;
@@ -576,6 +578,7 @@ static void
get_all_properties (Application * app)
{
if (app->props != NULL && app->props_cancel == NULL) {
+ app->props_cancel = g_cancellable_new();
g_dbus_proxy_call(app->props, "GetAll",
g_variant_new("(s)", NOTIFICATION_ITEM_DBUS_IFACE),
G_DBUS_CALL_FLAGS_NONE, -1, app->props_cancel,
@@ -745,6 +748,11 @@ application_free (Application * app)
if (app->guide != NULL) {
g_free(app->guide);
}
+ if (app->approver_cancels != NULL) {
+ g_list_foreach(app->approver_cancels, (GFunc)g_cancellable_cancel, NULL);
+ g_list_foreach(app->approver_cancels, (GFunc)g_object_unref, NULL);
+ g_list_free(app->approver_cancels);
+ }
if (app->approved_by != NULL) {
g_list_free(app->approved_by);
}
@@ -997,6 +1005,7 @@ application_service_appstore_application_add (ApplicationServiceAppstore * appst
app->guide = NULL;
app->currently_free = FALSE;
app->ordering_index = 0;
+ app->approver_cancels = NULL;
app->approved_by = NULL;
app->visible_state = VISIBLE_STATE_HIDDEN;
app->name_watcher = 0;
@@ -1110,6 +1119,11 @@ props_cb (GObject * object, GAsyncResult * res, gpointer user_data)
GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ return; // Must exit before accessing freed memory
+ }
+
if (app->props_cancel != NULL) {
g_object_unref(app->props_cancel);
app->props_cancel = NULL;
@@ -1283,6 +1297,24 @@ static void
remove_approver (gpointer papp, gpointer pproxy)
{
Application * app = (Application *)papp;
+
+ /* Check for any pending approvals and cancel them */
+ GList * iter = app->approver_cancels;
+ while (iter != NULL) {
+ GCancellable * cancel = (GCancellable *)iter->data;
+ GDBusProxy * proxy = (GDBusProxy *)g_object_get_data(G_OBJECT(cancel), "proxy");
+ if (proxy == pproxy) {
+ g_cancellable_cancel(cancel);
+ g_object_unref(cancel);
+
+ GList * next = iter->next;
+ app->approver_cancels = g_list_delete_link(app->approver_cancels, iter);
+ iter = next;
+ } else {
+ iter = iter->next;
+ }
+ }
+
app->approved_by = g_list_remove(app->approved_by, pproxy);
apply_status(app);
return;
@@ -1323,19 +1355,29 @@ static void
approver_request_cb (GObject *object, GAsyncResult *res, gpointer user_data)
{
GDBusProxy * proxy = G_DBUS_PROXY(object);
- Application * app = (Application *)user_data;
+ GCancellable * cancel = (GCancellable *)user_data;
GError * error = NULL;
gboolean approved = TRUE; /* default to approved */
GVariant * result;
result = g_dbus_proxy_call_finish(proxy, res, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ return; // Must exit before accessing freed memory
+ }
+
+ Application * app = (Application *)g_object_get_data(G_OBJECT(cancel), "app");
+ app->approver_cancels = g_list_remove(app->approver_cancels, cancel);
+ g_object_unref(cancel);
+
if (error == NULL) {
g_variant_get(result, "(b)", &approved);
g_debug("Approver responded: %s", approved ? "approve" : "rejected");
}
else {
g_debug("Approver responded error: %s", error->message);
+ g_error_free (error);
}
if (approved) {
@@ -1354,12 +1396,18 @@ check_with_new_approver (gpointer papp, gpointer papprove)
{
Application * app = (Application *)papp;
Approver * approver = (Approver *)papprove;
+ GCancellable * cancel = NULL;
+
+ cancel = g_cancellable_new();
+ g_object_set_data(G_OBJECT(cancel), "app", app);
+ g_object_set_data(G_OBJECT(cancel), "proxy", approver->proxy);
+ app->approver_cancels = g_list_prepend(app->approver_cancels, cancel);
g_dbus_proxy_call(approver->proxy, "ApproveItem",
g_variant_new("(ssuso)", app->id, app->category,
0, app->dbus_name, app->dbus_object),
- G_DBUS_CALL_FLAGS_NONE, -1, NULL,
- approver_request_cb, app);
+ G_DBUS_CALL_FLAGS_NONE, -1, cancel,
+ approver_request_cb, cancel);
return;
}