do_update_child_process (const char *installation_path, const char *ref, int socket_fd)
{
  g_autoptr(GOutputStream) out = g_unix_output_stream_new (socket_fd, TRUE);
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GFile) f = g_file_new_for_path (installation_path);
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  TransactionData transaction_data = { NULL };

  dir = flatpak_dir_get_by_path (f);

  if (!flatpak_dir_maybe_ensure_repo (dir, NULL, &error))
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  installation = flatpak_installation_new_for_dir (dir, NULL, &error);
  if (installation)
    transaction = flatpak_transaction_new_for_installation (installation, NULL, &error);
  if (transaction == NULL)
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  flatpak_transaction_add_default_dependency_sources (transaction);

  if (!flatpak_transaction_add_update (transaction, ref, NULL, NULL, &error))
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  transaction_data.out = out;

  g_signal_connect (transaction, "ready", G_CALLBACK (transaction_ready), &transaction_data);
  g_signal_connect (transaction, "new-operation", G_CALLBACK (transaction_new_operation), &transaction_data);
  g_signal_connect (transaction, "operation-done", G_CALLBACK (transaction_operation_done), &transaction_data);
  g_signal_connect (transaction, "operation-error", G_CALLBACK (transaction_operation_error), &transaction_data);

  if (!flatpak_transaction_run (transaction, NULL, &error))
    {
      if (!g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED)) /* If aborted we already sent error */
        send_progress (out, transaction_data.op, transaction_data.n_ops, transaction_data.progress,
                       PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  send_progress (out, transaction_data.op, transaction_data.n_ops, transaction_data.progress,
                 PROGRESS_STATUS_DONE, error);

  return 0;
}
do_update_child_process (const char *installation_path, const char *ref, int socket_fd)
{
  g_autoptr(GOutputStream) out = g_unix_output_stream_new (socket_fd, TRUE);
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakTransaction) transaction = NULL;
  g_autoptr(GFile) f = g_file_new_for_path (installation_path);
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  TransactionData transaction_data = { NULL };

  dir = flatpak_dir_get_by_path (f);

  if (!flatpak_dir_maybe_ensure_repo (dir, NULL, &error))
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  installation = flatpak_installation_new_for_dir (dir, NULL, &error);
  if (installation)
    transaction = flatpak_transaction_new_for_installation (installation, NULL, &error);
  if (transaction == NULL)
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  flatpak_transaction_add_default_dependency_sources (transaction);

  if (!flatpak_transaction_add_update (transaction, ref, NULL, NULL, &error))
    {
      send_progress (out, 0, 0, 0,
                     PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  transaction_data.out = out;

  g_signal_connect (transaction, "ready", G_CALLBACK (transaction_ready), &transaction_data);
  g_signal_connect (transaction, "new-operation", G_CALLBACK (transaction_new_operation), &transaction_data);
  g_signal_connect (transaction, "operation-done", G_CALLBACK (transaction_operation_done), &transaction_data);
  g_signal_connect (transaction, "operation-error", G_CALLBACK (transaction_operation_error), &transaction_data);

  if (!flatpak_transaction_run (transaction, NULL, &error))
    {
      if (!g_error_matches (error, FLATPAK_ERROR, FLATPAK_ERROR_ABORTED))  
        send_progress (out, transaction_data.op, transaction_data.n_ops, transaction_data.progress,
                       PROGRESS_STATUS_ERROR, error);
      return 0;
    }

  send_progress (out, transaction_data.op, transaction_data.n_ops, transaction_data.progress,
                 PROGRESS_STATUS_DONE, error);

  return 0;
}