Catch leaks in your unit tests

Let’s blog about my little trick that should be useful to everyone: Not everyone runs unit tests in valgrind, and even if they do it’s hard to see leaks from false-positive. Fortunately there is an easy way to catch GObject leaks in a unit test without using valgrind:

foo = my_object_new ();
g_object_add_weak_pointer (G_OBJECT (foo), (gpointer) &foo);
...
g_object_unref (foo);
g_assert (foo == NULL);

Do that on every object in your unit tests, it’s amazing what you can find…

Problems with Windows Live’s XMPP server

As you probably know (see here and there), it is possible to connect to MSN using the XMPP protocol with GNOME 3.4.

However, since last week, I think nobody can connect anymore. The reason is that MS server started using see-other-host, which is perfectly standard (part of XMPP CORE), but not implemented into telepathy-gabble. I can’t really blame them for this since they warned developers twice, and even then, it became effective much later than they announced.

The problem is described and patches are available in bug #51033, it should hit telepathy-gabble master soon. I’ll also consider backporting to stable branch, but patches are a bit intrusive…

There is a 2nd problem with WLM’s XMPP server that sometimes prevent us to connect. This time it is really a server issue out of our control. I’ve sent all needed logs and MS devs are actively working on the issue. However, retrying to connect multiple times (which we do by default) eventually succeed after some attempts.

Last but not least, it is possible to ADD (not REMOVE, wondering why their server does not accept that…) contacts in your MSN account. But WLM server uses a non-standard trick for that, to convert a Live account (e.g. user@live.com) to a jid (e.g. 1234@messenger.live.com). The non-standard iq are described here, and telepathy-gabble patches are available in bug #50341 to make it work.

I’m happy this is not useless work, since we have now over 10 000 monthly unique users connecting to MSN with XMPP through gnome-online-account (I’m app key owner, so I get usage stats).

Edit: telepathy-gabble 0.16.1 now released with a fix for the see-other-host issue.

Did you know g_clear_object/pointer() ?

g_clear_object() has been in glib since 2.28, and now g_clear_pointer() has landed in glib master (see bug #674634).
Their typical usage is to implement GObject::dispose, or “goto out” pattern, previously you would write:

void my_dispose (GObject *obj)
{
  MyObject *self = (MyObject *) obj;
  if (self->priv->object != NULL)
    {
      g_object_unref (self->priv->object);
      self->priv->object = NULL;
    }
  if (self->priv->hash != NULL)
    {
      g_hash_table_unref (self->priv->hash);
      self->priv->my_hash = NULL;
    }
  etc...
}

or:

void some_func ()
{
  GHashTable *tmp = NULL;

  ...
  if (error)
    goto out;

  tmp = g_hash_table_new();
  ...

out:
  if (tmp != NULL)
    g_hash_table_unref (tmp);
}

But now those becomes:

void my_dispose (GObject *obj)
{
  MyObject *self = (MyObject *) obj;

  g_clear_object (&self->priv->object);
  g_clear_pointer (&self->priv->hash, g_hash_table_unref);
  etc...
}

or:

void some_func ()
{
  GHashTable *tmp = NULL;

  ...
  if (error)
    goto out;

  tmp = g_hash_table_new();
  ...

out:
  g_clear_pointer (&tmp, g_hash_table_unref);
}

As extra bonus, g_clear_object() and g_clear_pointer() are thread-safe. That means that 2 threads can clear the same pointer at the same time and it will be freed only once. I’ve heard some code needs thread-safe dispose…

Thanks to Simon McVittie for the original idea in telepathy-glib where we had tp_clear_object/pointer for years.

GTestDBus – test your DBus app

Recently, I’ve been working on making GDBus’ unit test helpers as public API on libgio (see bug #672985). Thanks to the help from David Zeuthen, it landed in gio master as GTestDBus object.

The basic idea is simple: g_test_dbus_up() starts a dbus-daemon and sets DBUS_SESSION_BUS_ADDRESS env variable. That means that your tests will then be using that private session bus instead of messing with user’s. When the unit test is done, call g_test_dbus_down() which will kill the dbus-daemon. Of course in the case you unit test fails and crash, it still make sure the dbus-daemon will be cleaned.

And finally, thanks to Alexander Larsson, it even works on win32.

Enjoy 😀

git fork – quickly publish your git branches

When working with a new git project, I like to publish my patches in git branches on my public git server. I usually use the collabora git server, but some people also have account on freedesktop, etc. But it’s a bit long just to publish a branch:

  1. locally: git clone ssh://git.gnome.org/git/empathy
  2. locally: ssh git.collabora.co.uk
  3. collabora: cd public_html/git && git init --bare git://git.gnome.org/empathy
  4. locally: git remote add xclaesse git+ssh://git.collabora.co.uk/git/user/xclaesse/empathy

Note how GNOME urls are different in 1) and 3), not only the ssh:// VS git:// but also the extra /git/ and it’s different with freedesktop.

So my first step to simplify this is to define insteadOf URLs in ~/.gitconfig both locally and on server:

locally:

[url "ssh://git.gnome.org/git/"]
    insteadof = gnome:
[url "git+ssh://git.collabora.co.uk/git/user/xclaesse/"]
    insteadof = collabora:

on server:

[url "git://git.gnome.org/"]
    insteadof = gnome:

Now the steps are:

  1. locally: git clone gnome:empathy
  2. locally: ssh git.collabora.co.uk
  3. collabora: cd public_html/git && git init --bare gnome:empathy
  4. locally: git remote add xclaesse collabora:empathy

Still I’m lazy so I don’t like sshing the server manually, so the final step is to add this git alias in your local ~/.gitconfig:

[alias]
    fork = !git config --get remote.origin.url | xargs -n 1 ssh git.collabora.co.uk \"cd ~/public_html/git && git init --bare\"

That will create a public repository for the project you’re currently in, just by typing “git fork”! Steps are now:

  1. locally: git clone gnome:empathy
  2. locally: git fork
  3. locally: git remote add xclaesse collabora:empathy

Update: It’s more flexible with a python script, save it as “git-fork”, put it somewhere in your PATH and chmod +x

#!/usr/bin/python

import subprocess

remote_host = "git.collabora.co.uk"
git_remote_prefix = "collabora:"
git_remote_name = "zdra"

# Get current git repository's name
remote = subprocess.check_output(["git", "config", "--get", "remote.origin.url"]).strip()
name = remote[max (remote.rfind("/"), remote.rfind(":")) + 1:]
if not name.endswith(".git"):
    name = name + ".git"

# Create a remote repository
remote_cmd = "cd ~/public_html/git && git init --bare " + name
subprocess.call (["ssh", remote_host, remote_cmd])

# Add the remote repository to git remotes and push master
subprocess.call (["git", "remote", "add", git_remote_name, git_remote_prefix + name])
subprocess.call (["git", "push", git_remote_name, "master"])

SSH your N9 over 3G even with private IP

Thanks to Collabora, I’ve received an N9. So I’ve build ssh-contact package for it. It was easy since the N9 already has all its dependencies. I’ve simply taken debian’s package and rebuild it in scratchbox with the harmattan SDK.

Here are the packages:
ssh-contact_0.6-1_all.deb
ssh-contact-client_0.6-1_armel.deb
ssh-contact-service_0.6-1_armel.deb

To install them, you can follow the steps from here for example.

Updates on XMPP support in MSN

Good news for MSN users!

As explained in a previous post, Microsoft added XMPP support to connect MSN. A few days ago, they made it officially supported (previously was a developer preview only).

Thanks to the advice of a Microsoft developer, I even fixed the legal issue that prevented us to enable this by default. Client applications (as opposed to web applications) are not meant to ship the app secret key, even for closed source app (would be too easy to find the key in the binary). So there is a simple checkbox in the app settings to tell it is a “mobile application” and then it won’t need the secret key to authenticate.

All patches got merged and released into empathy (>=3.3.2), telepathy-gabble (>= 0.15.0), and gnome-online-accounts(>=3.3.0).

MSN in Empathy with XMPP

A month and a half ago, Microsoft announced that they had added XMPP to their Windows Live APIs. That means that any Jabber client could connect to MSN using our favorite open IM protocol! No more closed protocol to reverse-engineer.

Unfortunately, logging into their service is a bit more complex than just providing a login and password: they support only OAUTH2-like authentication. The good thing is that gnome-online-accounts already supports oauth2 for Facebook and Google services, and I’ve seen while googling that the mechanism is pretty much the same as Facebook. So I’ve downloaded Microsoft’s documentation (registration required to get it), created my own Windows Live application, copied GOA’s Facebook code to start with, and replaced the bits according to MS’ doc and got the login page!

Creating Windows Live account in GnomeOnlineAccounts

Unfortunately, from there it was failing to get the access-token, turns out the documentation contradicts itself. In one place they describe the exact same mechanism as existing code for Facebook, and the other places have small differences… I’ll let you guess which way actually worked 😉

The Windows Live account created in GnomeOnlineAccounts

Then I had to write in empathy-auth-client (an app usually used to ask user the password) code to instead take the access-token from GOA’s DBus API and give it to telepathy-gabble (our XMPP backend). After fixing a few bugs in telepathy-glib, telepathy-gabble and wocky, EUREKA! Got my MSN account connected in Empathy! Unfortunately it seems the features exposed by their XMPP server are really limited, just like Facebook’s XMPP.

My MSN contacts in Empathy

At the same time, I’ve also added support in Empathy to connect to Facebook GOA accounts, and authenticate them using goa’s access-token instead of having to repeat the password.

Code source is available in bugzilla, waiting for review:

Still, we have an important issue:
This new auth mechanism require us to register a Facebook/Windows Live application. An application consists of a public ID and a secret key. Since gnome-online-accounts is open source code, it means the app’s secret key would be readable from its source code (atm it is given as configure flag), meaning that anyone could make its own malware claiming being the “GNOME” application. This could be considered by Facebook/Microsoft a violation of their service (if I understood correctly). For Google service, it is not a problem because they offer an “anonymous” application and it is user’s choice to accept to grant permission or not (again, if I understood correctly).

Thanks to Collabora for letting me working on this!

Unified contact notifications

I’ve been working on gnome-shell’s IM notifications recently. The idea is to unify all notifications about a contact into the same bubble.

If you’re chatting in gnome-shell’s embedded chat and then the contact calls you, the “answer” and “reject” buttons gets into your chat instead of popping a new notification.

Call Approver

Then while the call is connected, the notification stay persistent and have a nice phone icon with call duration timer

Ongoing Call

What’s great with that design, is that if someone is calling you, there is a chat available right away to answer “sorry I’m busy, calling you later” and the reject the call.

Patches are attached on bug #656028