gboolean
gpm_phone_get_present (GpmPhone *phone, guint idx)
{
        g_return_val_if_fail (phone != NULL, FALSE);
        g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE);
        return phone->priv->present;
}
guint
gpm_phone_get_percentage (GpmPhone *phone, guint idx)
{
        g_return_val_if_fail (phone != NULL, 0);
        g_return_val_if_fail (GPM_IS_PHONE (phone), 0);
        return phone->priv->percentage;
}
static void
gpm_phone_num_batteries_changed (GDBusProxy *proxy,
                                 guint number,
                                 GpmPhone *phone)
{
        g_return_if_fail (GPM_IS_PHONE (phone));

        g_debug ("got NumberBatteriesChanged %i", number);
        if (number > 1) {
                g_warning ("number not 0 or 1, not valid!");
                return;
        }

        /* are we removed? */
        if (number == 0) {
                phone->priv->present = FALSE;
                phone->priv->percentage = 0;
                phone->priv->onac = FALSE;
                g_debug ("emitting device-removed : (%i)", 0);
                g_signal_emit (phone, signals [DEVICE_REMOVED], 0, 0);
                return;
        }

        if (phone->priv->present) {
                g_warning ("duplicate NumberBatteriesChanged with no change");
                return;
        }

        /* reset to defaults until we get BatteryStateChanged */
        phone->priv->present = TRUE;
        phone->priv->percentage = 0;
        phone->priv->onac = FALSE;
        g_debug ("emitting device-added : (%i)", 0);
        g_signal_emit (phone, signals [DEVICE_ADDED], 0, 0);
}
gboolean
gpm_phone_coldplug (GpmPhone *phone)
{
        GError  *error = NULL;
        GVariant *reply;
        gboolean ret;

        g_return_val_if_fail (phone != NULL, FALSE);
        g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE);

        if (phone->priv->proxy == NULL)
                return FALSE;

        reply = g_dbus_proxy_call_sync (phone->priv->proxy, "Coldplug",
                        NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
        if (error != NULL) {
                g_warning ("DEBUG: ERROR: %s", error->message);
                g_error_free (error);
        }

        if (reply != NULL) {
                ret = TRUE;
                g_variant_unref (reply);
        } else
                ret = FALSE;

        return ret;
}
guint
gpm_phone_get_num_batteries (GpmPhone *phone)
{
        g_return_val_if_fail (phone != NULL, 0);
        g_return_val_if_fail (GPM_IS_PHONE (phone), 0);
        if (phone->priv->present)
                return 1;
        return 0;
}
/**
 * gpm_phone_service_appeared_cb:
 */
static void
gpm_phone_service_appeared_cb (GDBusConnection *connection,
                               const gchar *name, const gchar *name_owner,
                               GpmPhone *phone)
{
    GError *error = NULL;

    g_return_if_fail (GPM_IS_PHONE (phone));

    if (phone->priv->connection == NULL) {
        egg_debug ("get connection");
        g_clear_error (&error);
        phone->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
        if (error != NULL) {
            egg_warning ("Could not connect to DBUS daemon: %s", error->message);
            g_error_free (error);
            phone->priv->connection = NULL;
            return;
        }
    }
    if (phone->priv->proxy == NULL) {
        egg_debug ("get proxy");
        g_clear_error (&error);
        phone->priv->proxy = dbus_g_proxy_new_for_name_owner (phone->priv->connection,
                             MATE_PHONE_MANAGER_DBUS_SERVICE,
                             MATE_PHONE_MANAGER_DBUS_PATH,
                             MATE_PHONE_MANAGER_DBUS_INTERFACE,
                             &error);
        if (error != NULL) {
            egg_warning ("Cannot connect, maybe the daemon is not running: %s", error->message);
            g_error_free (error);
            phone->priv->proxy = NULL;
            return;
        }

        /* complicated type. ick */
        dbus_g_object_register_marshaller(gpm_marshal_VOID__UINT_UINT_BOOLEAN,
                                          G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT,
                                          G_TYPE_BOOLEAN, G_TYPE_INVALID);

        /* get BatteryStateChanged */
        dbus_g_proxy_add_signal (phone->priv->proxy, "BatteryStateChanged",
                                 G_TYPE_UINT, G_TYPE_UINT, G_TYPE_BOOLEAN, G_TYPE_INVALID);
        dbus_g_proxy_connect_signal (phone->priv->proxy, "BatteryStateChanged",
                                     G_CALLBACK (gpm_phone_battery_state_changed),
                                     phone, NULL);

        /* get NumberBatteriesChanged */
        dbus_g_proxy_add_signal (phone->priv->proxy, "NumberBatteriesChanged",
                                 G_TYPE_UINT, G_TYPE_INVALID);
        dbus_g_proxy_connect_signal (phone->priv->proxy, "NumberBatteriesChanged",
                                     G_CALLBACK (gpm_phone_num_batteries_changed),
                                     phone, NULL);

    }
}
/** Invoked when we get the BatteryStateChanged
 */
static void
gpm_phone_battery_state_changed (DBusGProxy *proxy, guint idx, guint percentage, gboolean on_ac, GpmPhone *phone)
{
    g_return_if_fail (GPM_IS_PHONE (phone));

    egg_debug ("got BatteryStateChanged %i = %i (%i)", idx, percentage, on_ac);
    phone->priv->percentage = percentage;
    phone->priv->onac = on_ac;
    phone->priv->present = TRUE;
    egg_debug ("emitting device-refresh : (%i)", idx);
    g_signal_emit (phone, signals [DEVICE_REFRESH], 0, idx);
}
static void
gpm_phone_finalize (GObject *object)
{
        GpmPhone *phone;
        g_return_if_fail (GPM_IS_PHONE (object));

        phone = GPM_PHONE (object);
        phone->priv = GPM_PHONE_GET_PRIVATE (phone);

        if (phone->priv->proxy != NULL)
                g_object_unref (phone->priv->proxy);
        g_bus_unwatch_name (phone->priv->watch_id);

        G_OBJECT_CLASS (gpm_phone_parent_class)->finalize (object);
}
static void
gpm_phone_service_vanished_cb (GDBusConnection *connection,
                                const gchar *name,
                                GpmPhone *phone)
{
        g_return_if_fail (GPM_IS_PHONE (phone));

        if (phone->priv->proxy == NULL)
                return;
        g_debug ("removing proxy");
        g_object_unref (phone->priv->proxy);
        phone->priv->proxy = NULL;
        if (phone->priv->present) {
                phone->priv->present = FALSE;
                phone->priv->percentage = 0;
                g_debug ("emitting device-removed : (%i)", 0);
                g_signal_emit (phone, signals [DEVICE_REMOVED], 0, 0);
        }
}
static void
gpm_phone_service_appeared_cb (GDBusConnection *connection,
                               const gchar *name, const gchar *name_owner,
                               GpmPhone *phone)
{
        GError *error = NULL;

        g_return_if_fail (GPM_IS_PHONE (phone));

        if (phone->priv->connection == NULL) {
                g_debug ("get connection");
                g_clear_error (&error);
                phone->priv->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
                if (phone->priv->connection == NULL) {
                        g_warning ("Could not connect to DBUS daemon: %s", error->message);
                        g_error_free (error);
                        phone->priv->connection = NULL;
                        return;
                }
        }
        if (phone->priv->proxy == NULL) {
                g_debug ("get proxy");
                g_clear_error (&error);
                phone->priv->proxy = g_dbus_proxy_new_sync (phone->priv->connection,
                                G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                NULL,
                                CINNAMON_PHONE_MANAGER_DBUS_SERVICE,
                                CINNAMON_PHONE_MANAGER_DBUS_PATH,
                                CINNAMON_PHONE_MANAGER_DBUS_INTERFACE,
                                NULL, &error);
                if (phone->priv->proxy == NULL) {
                        g_warning ("Cannot connect, maybe the daemon is not running: %s", error->message);
                        g_error_free (error);
                        phone->priv->proxy = NULL;
                        return;
                }

                g_signal_connect (phone->priv->proxy, "g-signal", G_CALLBACK(gpm_phone_generic_signal_cb), phone);
        }
}
/**
 * gpm_phone_coldplug:
 * Return value: Success value, or zero for failure
 **/
gboolean
gpm_phone_coldplug (GpmPhone *phone)
{
    GError  *error = NULL;
    gboolean ret;

    g_return_val_if_fail (phone != NULL, FALSE);
    g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE);

    if (phone->priv->proxy == NULL) {
        egg_warning ("not connected");
        return FALSE;
    }

    ret = dbus_g_proxy_call (phone->priv->proxy, "Coldplug", &error,
                             G_TYPE_INVALID, G_TYPE_INVALID);
    if (error != NULL) {
        egg_warning ("DEBUG: ERROR: %s", error->message);
        g_error_free (error);
    }

    return ret;
}