check_for_updates (PortalFlatpakUpdateMonitor *monitor)
{
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  g_autoptr(GFile) installation_path = NULL;
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakInstalledRef) installed_ref = NULL;
  g_autoptr(FlatpakRemoteRef) remote_ref = NULL;
  const char *origin = NULL;
  const char *local_commit = NULL;
  const char *remote_commit;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  const char *ref;

  installation_path = update_monitor_get_installation_path (monitor);

  g_debug ("Checking for updates for %s/%s/%s in %s", m->name, m->arch, m->branch, flatpak_file_get_path_cached (installation_path));

  installation = lookup_installation_for_path (installation_path, &error);
  if (installation == NULL)
    {
      g_debug ("Unable to find installation for path %s: %s", flatpak_file_get_path_cached (installation_path), error->message);
      return;
    }

  installed_ref = flatpak_installation_get_installed_ref (installation,
                                                          FLATPAK_REF_KIND_APP,
                                                          m->name, m->arch, m->branch,
                                                          m->cancellable, &error);
  if (installed_ref == NULL)
    {
      g_debug ("getting installed ref failed: %s", error->message);
      return; /* Never report updates for uninstalled refs */
    }

  dir = flatpak_installation_get_dir (installation, NULL);
  if (dir == NULL)
    return;

  ref = flatpak_ref_format_ref_cached (FLATPAK_REF (installed_ref));
  if (flatpak_dir_ref_is_masked (dir, ref))
    return; /* Never report updates for masked refs */

  local_commit = flatpak_ref_get_commit (FLATPAK_REF (installed_ref));

  origin = flatpak_installed_ref_get_origin (installed_ref);

  remote_ref = flatpak_installation_fetch_remote_ref_sync (installation, origin,
                                                           FLATPAK_REF_KIND_APP,
                                                           m->name, m->arch, m->branch,
                                                           m->cancellable, &error);
  if (remote_ref == NULL)
    {
      /* Probably some network issue.
       * Fall back to the local_commit to at least be able to pick up already installed updates.
       */
      g_debug ("getting remote ref failed: %s", error->message);
      g_clear_error (&error);
      remote_commit = local_commit;
    }
  else
    {
      remote_commit = flatpak_ref_get_commit (FLATPAK_REF (remote_ref));
      if (remote_commit == NULL)
        {
          /* This can happen if we're offline and there is an update from an usb drive.
           * Not much we can do in terms of reporting it, but at least handle the case
           */
          g_debug ("Unknown remote commit, setting to local_commit");
          remote_commit = local_commit;
        }
    }

  if (g_strcmp0 (m->reported_local_commit, local_commit) != 0 ||
      g_strcmp0 (m->reported_remote_commit, remote_commit) != 0)
    {
      GVariantBuilder builder;
      gboolean is_closed;

      g_free (m->reported_local_commit);
      m->reported_local_commit = g_strdup (local_commit);

      g_free (m->reported_remote_commit);
      m->reported_remote_commit = g_strdup (remote_commit);

      g_debug ("Found update for %s/%s/%s, local: %s, remote: %s", m->name, m->arch, m->branch, local_commit, remote_commit);
      g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
      g_variant_builder_add (&builder, "{sv}", "running-commit", g_variant_new_string (m->commit));
      g_variant_builder_add (&builder, "{sv}", "local-commit", g_variant_new_string (local_commit));
      g_variant_builder_add (&builder, "{sv}", "remote-commit", g_variant_new_string (remote_commit));

      /* Maybe someone closed the monitor while we were checking for updates, then drop the signal.
       * There is still a minimal race between this check and the emit where a client could call close()
       * and still see the signal though. */
      g_mutex_lock (&m->lock);
      is_closed = m->closed;
      g_mutex_unlock (&m->lock);

      if (!is_closed &&
          !g_dbus_connection_emit_signal (update_monitor_get_connection (monitor),
                                          m->sender,
                                          m->obj_path,
                                          "org.freedesktop.portal.Flatpak.UpdateMonitor",
                                          "UpdateAvailable",
                                          g_variant_new ("(a{sv})", &builder),
                                          &error))
        {
          g_warning ("Failed to emit UpdateAvailable: %s", error->message);
          g_clear_error (&error);
        }
    }
}
check_for_updates (PortalFlatpakUpdateMonitor *monitor)
{
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  g_autoptr(GFile) installation_path = NULL;
  g_autoptr(FlatpakInstallation) installation = NULL;
  g_autoptr(FlatpakInstalledRef) installed_ref = NULL;
  g_autoptr(FlatpakRemoteRef) remote_ref = NULL;
  const char *origin = NULL;
  const char *local_commit = NULL;
  const char *remote_commit;
  g_autoptr(GError) error = NULL;
  g_autoptr(FlatpakDir) dir = NULL;
  const char *ref;

  installation_path = update_monitor_get_installation_path (monitor);

  g_debug ("Checking for updates for %s/%s/%s in %s", m->name, m->arch, m->branch, flatpak_file_get_path_cached (installation_path));

  installation = lookup_installation_for_path (installation_path, &error);
  if (installation == NULL)
    {
      g_debug ("Unable to find installation for path %s: %s", flatpak_file_get_path_cached (installation_path), error->message);
      return;
    }

  installed_ref = flatpak_installation_get_installed_ref (installation,
                                                          FLATPAK_REF_KIND_APP,
                                                          m->name, m->arch, m->branch,
                                                          m->cancellable, &error);
  if (installed_ref == NULL)
    {
      g_debug ("getting installed ref failed: %s", error->message);
      return;  
    }

  dir = flatpak_installation_get_dir (installation, NULL);
  if (dir == NULL)
    return;

  ref = flatpak_ref_format_ref_cached (FLATPAK_REF (installed_ref));
  if (flatpak_dir_ref_is_masked (dir, ref))
    return;  

  local_commit = flatpak_ref_get_commit (FLATPAK_REF (installed_ref));

  origin = flatpak_installed_ref_get_origin (installed_ref);

  remote_ref = flatpak_installation_fetch_remote_ref_sync (installation, origin,
                                                           FLATPAK_REF_KIND_APP,
                                                           m->name, m->arch, m->branch,
                                                           m->cancellable, &error);
  if (remote_ref == NULL)
    {
       
      g_debug ("getting remote ref failed: %s", error->message);
      g_clear_error (&error);
      remote_commit = local_commit;
    }
  else
    {
      remote_commit = flatpak_ref_get_commit (FLATPAK_REF (remote_ref));
      if (remote_commit == NULL)
        {
           
          g_debug ("Unknown remote commit, setting to local_commit");
          remote_commit = local_commit;
        }
    }

  if (g_strcmp0 (m->reported_local_commit, local_commit) != 0 ||
      g_strcmp0 (m->reported_remote_commit, remote_commit) != 0)
    {
      GVariantBuilder builder;
      gboolean is_closed;

      g_free (m->reported_local_commit);
      m->reported_local_commit = g_strdup (local_commit);

      g_free (m->reported_remote_commit);
      m->reported_remote_commit = g_strdup (remote_commit);

      g_debug ("Found update for %s/%s/%s, local: %s, remote: %s", m->name, m->arch, m->branch, local_commit, remote_commit);
      g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
      g_variant_builder_add (&builder, "{sv}", "running-commit", g_variant_new_string (m->commit));
      g_variant_builder_add (&builder, "{sv}", "local-commit", g_variant_new_string (local_commit));
      g_variant_builder_add (&builder, "{sv}", "remote-commit", g_variant_new_string (remote_commit));

       
      g_mutex_lock (&m->lock);
      is_closed = m->closed;
      g_mutex_unlock (&m->lock);

      if (!is_closed &&
          !g_dbus_connection_emit_signal (update_monitor_get_connection (monitor),
                                          m->sender,
                                          m->obj_path,
                                          "org.freedesktop.portal.Flatpak.UpdateMonitor",
                                          "UpdateAvailable",
                                          g_variant_new ("(a{sv})", &builder),
                                          &error))
        {
          g_warning ("Failed to emit UpdateAvailable: %s", error->message);
          g_clear_error (&error);
        }
    }
}