* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Authors: Xavier Claessens <xclaesse@gmail.com>
*/
#include <glib/gi18n-lib.h>
#include <dbus/dbus-glib.h>
+#include <telepathy-glib/account-manager.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/util.h>
-#include <libmissioncontrol/mc-enum-types.h>
#include "empathy-idle.h"
-#include "empathy-utils.h"
+#include "empathy-utils.h"
+#include "empathy-connectivity.h"
#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
#include "empathy-debug.h"
/* Number of seconds before entering extended autoaway. */
#define EXT_AWAY_TIME (30*60)
+/* Number of seconds to consider an account in the "just connected" state
+ * for. */
+#define ACCOUNT_IS_JUST_CONNECTED_SECONDS 10
+
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIdle)
typedef struct {
- MissionControl *mc;
DBusGProxy *gs_proxy;
- DBusGProxy *nm_proxy;
+ EmpathyConnectivity *connectivity;
+ gulong state_change_signal_id;
+
+ gboolean ready;
- McPresence state;
+ TpConnectionPresenceType state;
gchar *status;
- McPresence flash_state;
gboolean auto_away;
- gboolean use_nm;
- McPresence away_saved_state;
- McPresence nm_saved_state;
- gchar *nm_saved_status;
+ TpConnectionPresenceType away_saved_state;
+ TpConnectionPresenceType saved_state;
+ gchar *saved_status;
gboolean is_idle;
- gboolean nm_connected;
guint ext_away_timeout;
+
+ TpAccountManager *manager;
+ gulong idle_presence_changed_id;
+
+ /* pointer to a TpAccount --> glong of time of connection */
+ GHashTable *connect_times;
+
+ TpConnectionPresenceType requested_presence_type;
+ gchar *requested_status_message;
+
} EmpathyIdlePriv;
typedef enum {
- NM_STATE_UNKNOWN,
- NM_STATE_ASLEEP,
- NM_STATE_CONNECTING,
- NM_STATE_CONNECTED,
- NM_STATE_DISCONNECTED
-} NMState;
+ SESSION_STATUS_AVAILABLE,
+ SESSION_STATUS_INVISIBLE,
+ SESSION_STATUS_BUSY,
+ SESSION_STATUS_IDLE,
+ SESSION_STATUS_UNKNOWN
+} SessionStatus;
enum {
PROP_0,
PROP_STATE,
PROP_STATUS,
- PROP_FLASH_STATE,
- PROP_AUTO_AWAY,
- PROP_USE_NM
+ PROP_AUTO_AWAY
};
G_DEFINE_TYPE (EmpathyIdle, empathy_idle, G_TYPE_OBJECT);
static EmpathyIdle * idle_singleton = NULL;
+static const gchar *presence_type_to_status[NUM_TP_CONNECTION_PRESENCE_TYPES] = {
+ NULL,
+ "offline",
+ "available",
+ "away",
+ "xa",
+ "hidden",
+ "busy",
+ NULL,
+ NULL,
+};
+
static void
-idle_presence_changed_cb (MissionControl *mc,
- McPresence state,
+idle_presence_changed_cb (TpAccountManager *manager,
+ TpConnectionPresenceType state,
gchar *status,
+ gchar *status_message,
EmpathyIdle *idle)
{
EmpathyIdlePriv *priv;
priv = GET_PRIV (idle);
- DEBUG ("Presence changed to '%s' (%d)", status, state);
+ if (state == TP_CONNECTION_PRESENCE_TYPE_UNSET)
+ /* Assume our presence is offline if MC reports UNSET */
+ state = TP_CONNECTION_PRESENCE_TYPE_OFFLINE;
+
+ DEBUG ("Presence changed to '%s' (%d) \"%s\"", status, state,
+ status_message);
g_free (priv->status);
priv->state = state;
- priv->status = NULL;
- if (!EMP_STR_EMPTY (status)) {
- priv->status = g_strdup (status);
- }
+ if (EMP_STR_EMPTY (status_message))
+ priv->status = NULL;
+ else
+ priv->status = g_strdup (status_message);
g_object_notify (G_OBJECT (idle), "state");
g_object_notify (G_OBJECT (idle), "status");
priv = GET_PRIV (idle);
DEBUG ("Going to extended autoaway");
- empathy_idle_set_state (idle, MC_PRESENCE_EXTENDED_AWAY);
+ empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY);
priv->ext_away_timeout = 0;
return FALSE;
}
static void
-idle_session_idle_changed_cb (DBusGProxy *gs_proxy,
- gboolean is_idle,
- EmpathyIdle *idle)
+idle_session_status_changed_cb (DBusGProxy *gs_proxy,
+ SessionStatus status,
+ EmpathyIdle *idle)
{
EmpathyIdlePriv *priv;
+ gboolean is_idle;
priv = GET_PRIV (idle);
+ is_idle = (status == SESSION_STATUS_IDLE);
+
DEBUG ("Session idle state changed, %s -> %s",
priv->is_idle ? "yes" : "no",
is_idle ? "yes" : "no");
if (!priv->auto_away ||
- (priv->nm_saved_state == MC_PRESENCE_UNSET &&
- (priv->state <= MC_PRESENCE_OFFLINE ||
- priv->state == MC_PRESENCE_HIDDEN))) {
+ (priv->saved_state == TP_CONNECTION_PRESENCE_TYPE_UNSET &&
+ (priv->state <= TP_CONNECTION_PRESENCE_TYPE_OFFLINE ||
+ priv->state == TP_CONNECTION_PRESENCE_TYPE_HIDDEN))) {
/* We don't want to go auto away OR we explicitely asked to be
* offline, nothing to do here */
priv->is_idle = is_idle;
}
if (is_idle && !priv->is_idle) {
- McPresence new_state;
+ TpConnectionPresenceType new_state;
/* We are now idle */
idle_ext_away_start (idle);
- if (priv->nm_saved_state != MC_PRESENCE_UNSET) {
+ if (priv->saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) {
/* We are disconnected, when coming back from away
* we want to restore the presence before the
* disconnection. */
- priv->away_saved_state = priv->nm_saved_state;
+ priv->away_saved_state = priv->saved_state;
} else {
priv->away_saved_state = priv->state;
}
- new_state = MC_PRESENCE_AWAY;
- if (priv->state == MC_PRESENCE_EXTENDED_AWAY) {
- new_state = MC_PRESENCE_EXTENDED_AWAY;
+ new_state = TP_CONNECTION_PRESENCE_TYPE_AWAY;
+ if (priv->state == TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY) {
+ new_state = TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY;
}
DEBUG ("Going to autoaway. Saved state=%d, new state=%d",
priv->away_saved_state, new_state);
empathy_idle_set_state (idle, new_state);
} else if (!is_idle && priv->is_idle) {
- const gchar *new_status;
/* We are no more idle, restore state */
idle_ext_away_stop (idle);
- if (priv->away_saved_state == MC_PRESENCE_AWAY ||
- priv->away_saved_state == MC_PRESENCE_EXTENDED_AWAY) {
- priv->away_saved_state = MC_PRESENCE_AVAILABLE;
- new_status = NULL;
+ /* Only try and set the presence if the away saved state is not
+ * unset. This is an odd case because it means that the session
+ * didn't notify us of the state change to idle, and as a
+ * result, we couldn't save the current state at that time.
+ */
+ if (priv->away_saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) {
+ DEBUG ("Restoring state to %d",
+ priv->away_saved_state);
+
+ empathy_idle_set_state (idle,priv->away_saved_state);
} else {
- new_status = priv->status;
+ DEBUG ("Away saved state is unset. This means that we "
+ "weren't told when the session went idle. "
+ "As a result, I'm not trying to set presence");
}
- DEBUG ("Restoring state to %d, reset status to %s",
- priv->away_saved_state, new_status);
-
- empathy_idle_set_presence (idle,
- priv->away_saved_state,
- new_status);
-
- priv->away_saved_state = MC_PRESENCE_UNSET;
+ priv->away_saved_state = TP_CONNECTION_PRESENCE_TYPE_UNSET;
}
priv->is_idle = is_idle;
}
static void
-idle_nm_state_change_cb (DBusGProxy *proxy,
- guint state,
- EmpathyIdle *idle)
+idle_state_change_cb (EmpathyConnectivity *connectivity,
+ gboolean new_online,
+ EmpathyIdle *idle)
{
EmpathyIdlePriv *priv;
- gboolean old_nm_connected;
- gboolean new_nm_connected;
priv = GET_PRIV (idle);
- if (!priv->use_nm) {
- return;
- }
-
- old_nm_connected = priv->nm_connected;
- new_nm_connected = !(state == NM_STATE_CONNECTING ||
- state == NM_STATE_DISCONNECTED);
- priv->nm_connected = TRUE; /* To be sure _set_state will work */
-
- DEBUG ("New network state %d", state);
-
- if (old_nm_connected && !new_nm_connected) {
- /* We are no more connected */
+ if (!new_online) {
+ /* We are no longer connected */
DEBUG ("Disconnected: Save state %d (%s)",
priv->state, priv->status);
- priv->nm_saved_state = priv->state;
- g_free (priv->nm_saved_status);
- priv->nm_saved_status = g_strdup (priv->status);
- empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);
+ priv->saved_state = priv->state;
+ g_free (priv->saved_status);
+ priv->saved_status = g_strdup (priv->status);
+ empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_OFFLINE);
}
- else if (!old_nm_connected && new_nm_connected) {
+ else if (new_online
+ && priv->saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) {
/* We are now connected */
DEBUG ("Reconnected: Restore state %d (%s)",
- priv->nm_saved_state, priv->nm_saved_status);
+ priv->saved_state, priv->saved_status);
empathy_idle_set_presence (idle,
- priv->nm_saved_state,
- priv->nm_saved_status);
- priv->nm_saved_state = MC_PRESENCE_UNSET;
- g_free (priv->nm_saved_status);
- priv->nm_saved_status = NULL;
+ priv->saved_state,
+ priv->saved_status);
+ priv->saved_state = TP_CONNECTION_PRESENCE_TYPE_UNSET;
+ g_free (priv->saved_status);
+ priv->saved_status = NULL;
}
-
- priv->nm_connected = new_nm_connected;
}
static void
priv = GET_PRIV (object);
g_free (priv->status);
- g_object_unref (priv->mc);
+ g_free (priv->requested_status_message);
if (priv->gs_proxy) {
g_object_unref (priv->gs_proxy);
}
+ g_signal_handler_disconnect (priv->connectivity,
+ priv->state_change_signal_id);
+ priv->state_change_signal_id = 0;
+
+ if (priv->manager != NULL) {
+ g_signal_handler_disconnect (priv->manager,
+ priv->idle_presence_changed_id);
+ g_object_unref (priv->manager);
+ }
+
+ g_object_unref (priv->connectivity);
+
+ g_hash_table_destroy (priv->connect_times);
+ priv->connect_times = NULL;
+
idle_ext_away_stop (EMPATHY_IDLE (object));
}
(type, n_props, props);
idle_singleton = EMPATHY_IDLE (retval);
- g_object_add_weak_pointer (retval, (gpointer *) &idle_singleton);
+ g_object_add_weak_pointer (retval, (gpointer) &idle_singleton);
}
return retval;
}
+static const gchar *
+empathy_idle_get_status (EmpathyIdle *idle)
+{
+ EmpathyIdlePriv *priv;
+
+ priv = GET_PRIV (idle);
+
+ if (G_UNLIKELY (!priv->ready))
+ g_critical (G_STRLOC ": %s called before AccountManager ready",
+ G_STRFUNC);
+
+ if (!priv->status) {
+ return empathy_presence_get_default_message (priv->state);
+ }
+
+ return priv->status;
+}
+
static void
idle_get_property (GObject *object,
guint param_id,
case PROP_STATUS:
g_value_set_string (value, empathy_idle_get_status (idle));
break;
- case PROP_FLASH_STATE:
- g_value_set_enum (value, empathy_idle_get_flash_state (idle));
- break;
case PROP_AUTO_AWAY:
g_value_set_boolean (value, empathy_idle_get_auto_away (idle));
break;
- case PROP_USE_NM:
- g_value_set_boolean (value, empathy_idle_get_use_nm (idle));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
case PROP_STATUS:
empathy_idle_set_status (idle, g_value_get_string (value));
break;
- case PROP_FLASH_STATE:
- empathy_idle_set_flash_state (idle, g_value_get_enum (value));
- break;
case PROP_AUTO_AWAY:
empathy_idle_set_auto_away (idle, g_value_get_boolean (value));
break;
- case PROP_USE_NM:
- empathy_idle_set_use_nm (idle, g_value_get_boolean (value));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
g_object_class_install_property (object_class,
PROP_STATE,
- g_param_spec_enum ("state",
+ g_param_spec_uint ("state",
"state",
"state",
- MC_TYPE_PRESENCE,
- MC_PRESENCE_AVAILABLE,
+ 0, NUM_TP_CONNECTION_PRESENCE_TYPES,
+ TP_CONNECTION_PRESENCE_TYPE_UNSET,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_STATUS,
"status",
NULL,
G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_FLASH_STATE,
- g_param_spec_enum ("flash-state",
- "flash-state",
- "flash-state",
- MC_TYPE_PRESENCE,
- MC_PRESENCE_UNSET,
- G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_AUTO_AWAY,
FALSE,
G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_USE_NM,
- g_param_spec_boolean ("use-nm",
- "Use Network Manager",
- "Set presence according to Network Manager",
- FALSE,
- G_PARAM_READWRITE));
-
g_type_class_add_private (object_class, sizeof (EmpathyIdlePriv));
}
+static void
+account_status_changed_cb (TpAccount *account,
+ guint old_status,
+ guint new_status,
+ guint reason,
+ gchar *dbus_error_name,
+ GHashTable *details,
+ gpointer user_data)
+{
+ EmpathyIdle *idle = EMPATHY_IDLE (user_data);
+ EmpathyIdlePriv *priv = GET_PRIV (idle);
+ GTimeVal val;
+
+ if (new_status == TP_CONNECTION_STATUS_CONNECTED) {
+ g_get_current_time (&val);
+ g_hash_table_insert (priv->connect_times, account,
+ GINT_TO_POINTER (val.tv_sec));
+ } else if (new_status == TP_CONNECTION_STATUS_DISCONNECTED) {
+ g_hash_table_remove (priv->connect_times, account);
+ }
+}
+
+static void
+account_manager_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EmpathyIdle *idle = user_data;
+ TpAccountManager *account_manager = TP_ACCOUNT_MANAGER (source_object);
+ EmpathyIdlePriv *priv;
+ TpConnectionPresenceType state;
+ gchar *status, *status_message;
+ GList *accounts, *l;
+ GError *error = NULL;
+
+ /* In case we've been finalized before reading this callback */
+ if (idle_singleton == NULL)
+ return;
+
+ priv = GET_PRIV (idle);
+ priv->ready = TRUE;
+
+ if (!tp_account_manager_prepare_finish (account_manager, result, &error)) {
+ DEBUG ("Failed to prepare account manager: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ state = tp_account_manager_get_most_available_presence (priv->manager,
+ &status, &status_message);
+
+ idle_presence_changed_cb (account_manager, state, status,
+ status_message, idle);
+
+ accounts = tp_account_manager_get_valid_accounts (priv->manager);
+ for (l = accounts; l != NULL; l = l->next) {
+ tp_g_signal_connect_object (l->data, "status-changed",
+ G_CALLBACK (account_status_changed_cb),
+ idle, 0);
+ }
+ g_list_free (accounts);
+
+ g_free (status);
+ g_free (status_message);
+}
+
static void
empathy_idle_init (EmpathyIdle *idle)
{
- DBusGConnection *system_bus;
- GError *error = NULL;
EmpathyIdlePriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (idle,
EMPATHY_TYPE_IDLE, EmpathyIdlePriv);
+ TpDBusDaemon *dbus;
idle->priv = priv;
priv->is_idle = FALSE;
- priv->mc = empathy_mission_control_dup_singleton ();
- priv->state = mission_control_get_presence_actual (priv->mc, &error);
- if (error) {
- DEBUG ("Error getting actual presence: %s", error->message);
- priv->state = MC_PRESENCE_UNSET;
- g_clear_error (&error);
- }
- priv->status = mission_control_get_presence_message_actual (priv->mc, &error);
- if (error || EMP_STR_EMPTY (priv->status)) {
- g_free (priv->status);
- priv->status = NULL;
+ priv->manager = tp_account_manager_dup ();
- if (error) {
- DEBUG ("Error getting actual presence message: %s", error->message);
- g_clear_error (&error);
- }
- }
+ tp_account_manager_prepare_async (priv->manager, NULL,
+ account_manager_ready_cb, idle);
+
+ priv->idle_presence_changed_id = g_signal_connect (priv->manager,
+ "most-available-presence-changed",
+ G_CALLBACK (idle_presence_changed_cb), idle);
- dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
- "PresenceChanged",
- G_CALLBACK (idle_presence_changed_cb),
- idle, NULL);
+ dbus = tp_dbus_daemon_dup (NULL);
- priv->gs_proxy = dbus_g_proxy_new_for_name (tp_get_bus (),
- "org.gnome.ScreenSaver",
- "/org/gnome/ScreenSaver",
- "org.gnome.ScreenSaver");
+ priv->gs_proxy = dbus_g_proxy_new_for_name (
+ tp_proxy_get_dbus_connection (dbus),
+ "org.gnome.SessionManager",
+ "/org/gnome/SessionManager/Presence",
+ "org.gnome.SessionManager.Presence");
if (priv->gs_proxy) {
- dbus_g_proxy_add_signal (priv->gs_proxy, "SessionIdleChanged",
- G_TYPE_BOOLEAN,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->gs_proxy, "SessionIdleChanged",
- G_CALLBACK (idle_session_idle_changed_cb),
+ dbus_g_proxy_add_signal (priv->gs_proxy, "StatusChanged",
+ G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->gs_proxy, "StatusChanged",
+ G_CALLBACK (idle_session_status_changed_cb),
idle, NULL);
} else {
DEBUG ("Failed to get gs proxy");
}
+ g_object_unref (dbus);
- system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
- if (!system_bus) {
- DEBUG ("Failed to get system bus: %s",
- error ? error->message : "No error given");
- } else {
- priv->nm_proxy = dbus_g_proxy_new_for_name (system_bus,
- "org.freedesktop.NetworkManager",
- "/org/freedesktop/NetworkManager",
- "org.freedesktop.NetworkManager");
- }
- if (priv->nm_proxy) {
- dbus_g_proxy_add_signal (priv->nm_proxy, "StateChange",
- G_TYPE_UINT, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->nm_proxy, "StateChange",
- G_CALLBACK (idle_nm_state_change_cb),
- idle, NULL);
- } else {
- DEBUG ("Failed to get nm proxy");
- }
+ priv->connectivity = empathy_connectivity_dup_singleton ();
+ priv->state_change_signal_id = g_signal_connect (priv->connectivity,
+ "state-change", G_CALLBACK (idle_state_change_cb), idle);
- priv->nm_connected = TRUE;
+ priv->connect_times = g_hash_table_new (g_direct_hash, g_direct_equal);
}
EmpathyIdle *
return g_object_new (EMPATHY_TYPE_IDLE, NULL);
}
-McPresence
+TpConnectionPresenceType
empathy_idle_get_state (EmpathyIdle *idle)
{
EmpathyIdlePriv *priv;
priv = GET_PRIV (idle);
+ if (G_UNLIKELY (!priv->ready))
+ g_critical (G_STRLOC ": %s called before AccountManager ready",
+ G_STRFUNC);
+
return priv->state;
}
void
empathy_idle_set_state (EmpathyIdle *idle,
- McPresence state)
+ TpConnectionPresenceType state)
{
EmpathyIdlePriv *priv;
empathy_idle_set_presence (idle, state, priv->status);
}
-const gchar *
-empathy_idle_get_status (EmpathyIdle *idle)
-{
- EmpathyIdlePriv *priv;
-
- priv = GET_PRIV (idle);
-
- if (!priv->status) {
- return empathy_presence_get_default_message (priv->state);
- }
-
- return priv->status;
-}
-
void
empathy_idle_set_status (EmpathyIdle *idle,
const gchar *status)
empathy_idle_set_presence (idle, priv->state, status);
}
-McPresence
-empathy_idle_get_flash_state (EmpathyIdle *idle)
-{
- EmpathyIdlePriv *priv;
-
- priv = GET_PRIV (idle);
-
- return priv->flash_state;
-}
-
-void
-empathy_idle_set_flash_state (EmpathyIdle *idle,
- McPresence state)
+static void
+empathy_idle_do_set_presence (EmpathyIdle *idle,
+ TpConnectionPresenceType status_type,
+ const gchar *status_message)
{
- EmpathyIdlePriv *priv;
+ EmpathyIdlePriv *priv = GET_PRIV (idle);
+ const gchar *status;
- priv = GET_PRIV (idle);
+ g_assert (status_type > 0 && status_type < NUM_TP_CONNECTION_PRESENCE_TYPES);
- priv->flash_state = state;
+ status = presence_type_to_status[status_type];
- if (state == MC_PRESENCE_UNSET) {
- }
+ g_return_if_fail (status != NULL);
- g_object_notify (G_OBJECT (idle), "flash-state");
+ /* We possibly should be sure that the account manager is prepared, but
+ * sometimes this isn't possible, like when exiting. In other words,
+ * we need a callback to empathy_idle_set_presence to be sure the
+ * presence is set on all accounts successfully.
+ * However, in practice, this is fine as we've already prepared the
+ * account manager here in _init. */
+ tp_account_manager_set_all_requested_presences (priv->manager,
+ status_type, status, status_message);
}
void
empathy_idle_set_presence (EmpathyIdle *idle,
- McPresence state,
+ TpConnectionPresenceType state,
const gchar *status)
{
EmpathyIdlePriv *priv;
DEBUG ("Changing presence to %s (%d)", status, state);
+ g_free (priv->requested_status_message);
+ priv->requested_presence_type = state;
+ priv->requested_status_message = g_strdup (status);
+
/* Do not set translated default messages */
default_status = empathy_presence_get_default_message (state);
if (!tp_strdiff (status, default_status)) {
status = NULL;
}
- if (!priv->nm_connected) {
- DEBUG ("NM not connected");
+ if (state != TP_CONNECTION_PRESENCE_TYPE_OFFLINE &&
+ !empathy_connectivity_is_online (priv->connectivity)) {
+ DEBUG ("Empathy is not online");
- priv->nm_saved_state = state;
+ priv->saved_state = state;
if (tp_strdiff (priv->status, status)) {
- g_free (priv->status);
- priv->status = NULL;
+ g_free (priv->saved_status);
+ priv->saved_status = NULL;
if (!EMP_STR_EMPTY (status)) {
- priv->status = g_strdup (status);
+ priv->saved_status = g_strdup (status);
}
- g_object_notify (G_OBJECT (idle), "status");
}
-
return;
}
- mission_control_set_presence (priv->mc, state, status, NULL, NULL);
+ empathy_idle_do_set_presence (idle, state, status);
}
gboolean
g_object_notify (G_OBJECT (idle), "auto-away");
}
-gboolean
-empathy_idle_get_use_nm (EmpathyIdle *idle)
+TpConnectionPresenceType
+empathy_idle_get_requested_presence (EmpathyIdle *idle,
+ gchar **status,
+ gchar **status_message)
{
EmpathyIdlePriv *priv = GET_PRIV (idle);
- return priv->use_nm;
+ if (status != NULL) {
+ *status = g_strdup (presence_type_to_status[priv->requested_presence_type]);
+ }
+
+ if (status_message != NULL) {
+ *status_message = g_strdup (priv->requested_status_message);
+ }
+
+ return priv->requested_presence_type;
}
-void
-empathy_idle_set_use_nm (EmpathyIdle *idle,
- gboolean use_nm)
+/* This function returns %TRUE if EmpathyIdle considers the account
+ * @account as having just connected recently. Otherwise, it returns
+ * %FALSE. In doubt, %FALSE is returned. */
+gboolean
+empathy_idle_account_is_just_connected (EmpathyIdle *idle,
+ TpAccount *account)
{
EmpathyIdlePriv *priv = GET_PRIV (idle);
+ GTimeVal val;
+ gpointer ptr;
+ glong t;
- if (!priv->nm_proxy || use_nm == priv->use_nm) {
- return;
+ if (tp_account_get_connection_status (account, NULL)
+ != TP_CONNECTION_STATUS_CONNECTED) {
+ return FALSE;
}
- priv->use_nm = use_nm;
+ ptr = g_hash_table_lookup (priv->connect_times, account);
- if (use_nm) {
- guint nm_status;
- GError *error = NULL;
+ if (ptr == NULL) {
+ return FALSE;
+ }
- dbus_g_proxy_call (priv->nm_proxy, "state",
- &error,
- G_TYPE_INVALID,
- G_TYPE_UINT, &nm_status,
- G_TYPE_INVALID);
+ t = GPOINTER_TO_INT (ptr);
- if (error) {
- DEBUG ("Couldn't get NM state: %s", error->message);
- g_clear_error (&error);
- nm_status = NM_STATE_ASLEEP;
- }
-
- idle_nm_state_change_cb (priv->nm_proxy, nm_status, idle);
- } else {
- priv->nm_connected = TRUE;
- if (priv->nm_saved_state != MC_PRESENCE_UNSET) {
- empathy_idle_set_state (idle, priv->nm_saved_state);
- }
- priv->nm_saved_state = MC_PRESENCE_UNSET;
- }
+ g_get_current_time (&val);
- g_object_notify (G_OBJECT (idle), "use-nm");
+ return (val.tv_sec - t) < ACCOUNT_IS_JUST_CONNECTED_SECONDS;
}
-