telepathy-mission-control: McdAccount: store automatic presence as a single attribute

Simon McVittie smcv at kemper.freedesktop.org
Wed Feb 13 06:45:04 PST 2013


Module: telepathy-mission-control
Branch: master
Commit: 5b21fc3d06fba26dfef4ebd5e4287e57e1a416db
URL:    http://cgit.freedesktop.org/telepathy/telepathy-mission-control/commit/?id=5b21fc3d06fba26dfef4ebd5e4287e57e1a416db

Author: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date:   Wed Sep 12 12:20:29 2012 +0100

McdAccount: store automatic presence as a single attribute

This will be necessary to make its change-notification work correctly.

Use tests/twisted/account-manager/auto-connect.py to exercise the
automatic migration.

account-storage/default-keyring-storage.py is broken by this change,
because it asserts that keyfiles from a lower-priority XDG location
are not automatically migrated to a higher-priority location until
something actually changes, and the migration of AutomaticPresenceType
is a change. To avoid that, put the automatic presence in lower-priority
keyfiles in that test in the new format already.

---

 src/mcd-account-config.h                           |    3 +
 src/mcd-account.c                                  |   92 +++++++++++++------
 src/mcd-storage.c                                  |    3 +
 tests/twisted/account-manager/auto-connect.py      |   20 ++++-
 .../account-storage/default-keyring-storage.py     |    2 +
 5 files changed, 90 insertions(+), 30 deletions(-)

diff --git a/src/mcd-account-config.h b/src/mcd-account-config.h
index 3124692..fc7a9ea 100644
--- a/src/mcd-account-config.h
+++ b/src/mcd-account-config.h
@@ -39,6 +39,8 @@
 #define MC_ACCOUNTS_KEY_NORMALIZED_NAME "NormalizedName"
 #define MC_ACCOUNTS_KEY_AVATAR_TOKEN "avatar_token"
 #define MC_ACCOUNTS_KEY_AVATAR_MIME "AvatarMime"
+#define MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE "AutomaticPresence"
+/* next two are obsoleted by MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE */
 #define MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS "AutomaticPresenceStatus"
 #define MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE "AutomaticPresenceMessage"
 #define MC_ACCOUNTS_KEY_ICON "Icon"
@@ -47,6 +49,7 @@
 /* ... also "condition-*" reserved by mcd-account-conditions.c */
 
 /* unsigned 32-bit integer, 'u' */
+/* obsoleted by MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE */
 #define MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE "AutomaticPresenceType"
 
 /* boolean, 'b' */
diff --git a/src/mcd-account.c b/src/mcd-account.c
index 031ed3f..691e165 100644
--- a/src/mcd-account.c
+++ b/src/mcd-account.c
@@ -1491,21 +1491,9 @@ set_automatic_presence (TpSvcDBusProperties *self,
 
     if (changed)
     {
-        GValue presence = G_VALUE_INIT;
-
-        g_value_init (&presence, G_TYPE_INT);
-        g_value_set_int (&presence, priv->auto_presence_type);
-
         mcd_storage_set_attribute (priv->storage, account_name,
-                                   MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE,
-                                   &presence);
-        mcd_storage_set_string (priv->storage, account_name,
-                                MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS,
-                                priv->auto_presence_status);
-        mcd_storage_set_string (priv->storage, account_name,
-                                MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE,
-                                priv->auto_presence_message);
-
+                                   MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE,
+                                   value);
         mcd_storage_commit (priv->storage, account_name);
         mcd_account_changed_property (account, name, value);
     }
@@ -3083,32 +3071,78 @@ mcd_account_setup (McdAccount *account)
     priv->always_dispatch =
       mcd_storage_get_boolean (storage, name, MC_ACCOUNTS_KEY_ALWAYS_DISPATCH);
 
-    /* load the automatic presence */
-    priv->auto_presence_type =
-      mcd_storage_get_integer (storage, name,
-                               MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE);
+    g_value_init (&value, TP_STRUCT_TYPE_SIMPLE_PRESENCE);
 
-    /* If invalid or something, force it to AVAILABLE - we want the auto
-     * presence type to be an online status */
-    if (!_presence_type_is_online (priv->auto_presence_type))
+    g_free (priv->auto_presence_status);
+    g_free (priv->auto_presence_message);
+
+    if (mcd_storage_get_attribute (storage, name,
+                                   MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE, &value,
+                                   NULL))
     {
-        priv->auto_presence_type = TP_CONNECTION_PRESENCE_TYPE_AVAILABLE;
-        g_free (priv->auto_presence_status);
-        priv->auto_presence_status = g_strdup ("available");
+        GValueArray *va = g_value_get_boxed (&value);
+
+        priv->auto_presence_type = g_value_get_uint (va->values + 0);
+        priv->auto_presence_status = g_value_dup_string (va->values + 1);
+        priv->auto_presence_message = g_value_dup_string (va->values + 2);
+
+        if (priv->auto_presence_status == NULL)
+            priv->auto_presence_status = g_strdup ("");
+        if (priv->auto_presence_message == NULL)
+            priv->auto_presence_message = g_strdup ("");
     }
     else
     {
-        g_free (priv->auto_presence_status);
+        /* try the old versions */
+        priv->auto_presence_type =
+          mcd_storage_get_integer (storage, name,
+                                   MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE);
         priv->auto_presence_status =
           mcd_storage_dup_string (storage, name,
                                   MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS);
+        priv->auto_presence_message =
+          mcd_storage_dup_string (storage, name,
+                                  MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE);
+
+        if (priv->auto_presence_status == NULL)
+            priv->auto_presence_status = g_strdup ("");
+        if (priv->auto_presence_message == NULL)
+            priv->auto_presence_message = g_strdup ("");
+
+        /* migrate to a more sensible storage format */
+        g_value_take_boxed (&value, tp_value_array_build (3,
+                G_TYPE_UINT, (guint) priv->auto_presence_type,
+                G_TYPE_STRING, priv->auto_presence_status,
+                G_TYPE_STRING, priv->auto_presence_message,
+                G_TYPE_INVALID));
+
+        if (mcd_storage_set_attribute (storage, name,
+                                       MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE,
+                                       &value))
+        {
+            mcd_storage_set_attribute (storage, name,
+                                       MC_ACCOUNTS_KEY_AUTO_PRESENCE_TYPE,
+                                       NULL);
+            mcd_storage_set_attribute (storage, name,
+                                       MC_ACCOUNTS_KEY_AUTO_PRESENCE_STATUS,
+                                       NULL);
+            mcd_storage_set_attribute (storage, name,
+                                       MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE,
+                                       NULL);
+            mcd_storage_commit (storage, name);
+        }
     }
 
-    g_free (priv->auto_presence_message);
-    priv->auto_presence_message =
-      mcd_storage_dup_string (storage, name,
-                              MC_ACCOUNTS_KEY_AUTO_PRESENCE_MESSAGE);
+    /* If invalid or something, force it to AVAILABLE - we want the auto
+     * presence type to be an online status */
+    if (!_presence_type_is_online (priv->auto_presence_type))
+    {
+        priv->auto_presence_type = TP_CONNECTION_PRESENCE_TYPE_AVAILABLE;
+        g_free (priv->auto_presence_status);
+        priv->auto_presence_status = g_strdup ("available");
+    }
 
+    g_value_unset (&value);
     g_value_init (&value, TP_ARRAY_TYPE_OBJECT_PATH_LIST);
 
     if (priv->supersedes != NULL)
diff --git a/src/mcd-storage.c b/src/mcd-storage.c
index 7799752..0670d5e 100644
--- a/src/mcd-storage.c
+++ b/src/mcd-storage.c
@@ -299,6 +299,9 @@ static struct {
 } known_attributes[] = {
     /* Please keep this sorted by type, then by name. */
 
+    /* Structs */
+      { "(uss)", MC_ACCOUNTS_KEY_AUTOMATIC_PRESENCE },
+
     /* Array of object path */
       { "ao", MC_ACCOUNTS_KEY_SUPERSEDES },
 
diff --git a/tests/twisted/account-manager/auto-connect.py b/tests/twisted/account-manager/auto-connect.py
index d626983..a623902 100644
--- a/tests/twisted/account-manager/auto-connect.py
+++ b/tests/twisted/account-manager/auto-connect.py
@@ -51,6 +51,7 @@ def preseed(q, bus, fake_accounts_service):
         'NormalizedName': 'jc.denton at unatco.int',
         'Enabled': True,
         'ConnectAutomatically': True,
+        # These are in the old format. They'll be combined shortly.
         'AutomaticPresenceType': dbus.UInt32(2),
         'AutomaticPresenceStatus': 'available',
         'AutomaticPresenceMessage': 'My vision is augmented',
@@ -85,7 +86,24 @@ def test(q, bus, unused, **kwargs):
             'password': r'\\ionstorm\\',
             }
 
-    mc = MC(q, bus)
+    mc = MC(q, bus, wait_for_names=False)
+    mc.wait_for_names(
+            # Migration step: the three separate attributes get combined
+            # (before the names are taken, so we need to expect it here)
+            EventPattern('dbus-method-call',
+                interface=cs.TEST_DBUS_ACCOUNT_SERVICE_IFACE,
+                method='UpdateAttributes',
+                predicate=(lambda e:
+                    e.args[0] == account_id and
+                    e.args[1] == {'AutomaticPresence':
+                        (2, 'available', 'My vision is augmented')} and
+                    e.args[2] == {'AutomaticPresence': 0} and   # flags
+                    set(e.args[3]) == set([     # no particular order
+                        'AutomaticPresenceType',
+                        'AutomaticPresenceStatus',
+                        'AutomaticPresenceMessage',
+                        ])))
+            )
 
     request_conn, prop_changed = q.expect_many(
             EventPattern('dbus-method-call', method='RequestConnection',
diff --git a/tests/twisted/account-storage/default-keyring-storage.py b/tests/twisted/account-storage/default-keyring-storage.py
index 903df86..f41bc17 100644
--- a/tests/twisted/account-storage/default-keyring-storage.py
+++ b/tests/twisted/account-storage/default-keyring-storage.py
@@ -242,6 +242,7 @@ protocol=fakeprotocol
 param-account=dontdivert at example.com
 param-password=password_in_keyfile
 DisplayName=New and improved account
+AutomaticPresence=2;available;;
 """ % group)
 
     account_manager, properties, interfaces = resuscitate_mc(q, bus, mc)
@@ -292,6 +293,7 @@ manager=fakecm
 protocol=fakeprotocol
 param-account=dontdivert at example.com
 DisplayName=Ye olde account
+AutomaticPresence=2;available;;
 """ % group)
 
     account_manager, properties, interfaces = resuscitate_mc(q, bus, mc)



More information about the telepathy-commits mailing list