Reply
Thread Tools
Posts: 249 | Thanked: 277 times | Joined on May 2010 @ Brighton, UK
#1
Ok, I'm working on my first Maemo5 project (QtCreator/C++) to get a feel for things, and the next stage is to query and preserve the status of all the accounts, disable them, then do stuff, and finally restore them.

Easy-peesy. DBus query to grab the state, DBus calls to disable them all, then DBus calls to restore the saved values.

Thing is, the version of Telepathy in the QtCreator SDK seems quite old, and doesn't have the convenience methods for getting and setting the DBus properties, so you have to use the generic DBus property methods.

My issue is that I've been mostly using Qt up to this point, with just a sprinkling of glib thrown in as required, so I have no idea if I'm missing something fundamental. The blocking calls (tp_cli_dbus_properties_run_get) are deprecated, and the async calls (tp_cli_dbus_properties_call_get) run from the event loop. Thus, the callbacks fire when the reply is received, but I've no idea what the correct way is to determine when this has completed.

It essentially becomes a bit more complicated due to the fact that there are two callbacks involved; the first to identify the accounts, and the second group are set up from that callback for each account to query the property values. I can (IMHO) bodge it by noting the number of accounts returned, and then waiting until I have that many property callbacks fired...but this seems a poor way of doing things, and I'm sure I must be missing something...

...any ideas?

Last edited by mr_jrt; 2011-06-17 at 13:25.
 
epage's Avatar
Posts: 1,684 | Thanked: 1,562 times | Joined on Jun 2008 @ Austin, TX
#2
First you might want to clarify the title of this thread that this is fundamental issues in using Telepathy and not fundamental issues in Telepathy. Making the change would decrease the chance of negative tangentials that would not contribute to helping resolve your problem.

Originally Posted by mr_jrt View Post
Ok, I'm working on my first Maemo5 project (QtCreator/C++) to get a feel for things, and the next stage is to query and preserve the status of all the accounts, disable them, then do stuff, and finally restore them.

Easy-peesy. DBus query to grab the state, DBus calls to disable them all, then DBus calls to restore the saved values.

Thing is, the version of Telepathy in the QtCreator SDK seems quite old, and doesn't have the convenience methods for getting and setting the DBus properties, so you have to use the generic DBus property methods.

My issue is that I've been mostly using Qt up to this point, with just a sprinkling of glib thrown in as required, so I have no idea if I'm missing something fundamental. The blocking calls (tp_cli_dbus_properties_run_get) are deprecated, and the async calls (tp_cli_dbus_properties_call_get) run from the event loop. Thus, the callbacks fire when the reply is received, but I've no idea what the correct way is to determine when this has completed.

It essentially becomes a bit more complicated due to the fact that there are two callbacks involved; the first to identify the accounts, and the second group are set up from that callback for each account to query the property values. I can (IMHO) bodge it by noting the number of accounts returned, and then waiting until I have that many property callbacks fired...but this seems a poor way of doing things, and I'm sure I must be missing something...

...any ideas?
Let's see if I understand the problem. For each account you need to send/receive a message and based on that message you need to send/receive another?

Normally how I handle this is good book keeping. Keep in mind that you should get error replies if one fails so you shouldn't have problems with waiting forever due to a problem (unless there is some weird bug on either side).

The nice thing about the use of callbacks is that even in a buggy condition you can end up having a user cancel the request (assuming this is a GUI app). The other nice aspect is you can fire all of the callbacks in parallel and and process the second ones in parallel and then join them all at the end.

You can use objects dedicated to this to help with the book keeping or you might be able to use QSignalMapper.

I have an example of tracking all of this but it is in Python and uses DBus through GLib rather than Qt but maybe it'd help. Its meant to watch for calls, check if they are incoming but not picked up, so I can refresh voicemail.

Top Level
https://github.com/epage/DialCentral...all_handler.py
Utility Classes
https://github.com/epage/DialCentral...il/tp_utils.py
__________________
770, n810, n900, Ideapad S10-3t
TheOneRing, DialCentral, Gonvert, Quicknote, Multilist, ejpi, nQa, Waters of Shiloah
Programming Blog
 

The Following User Says Thank You to epage For This Useful Post:
Posts: 249 | Thanked: 277 times | Joined on May 2010 @ Brighton, UK
#3
Thanks for the reply. I appreciate your point with the thread title....changed

Python's next on my to-learn list...the python dbus examples I've stumbled across have all used nice blocking code in them, which makes me somewhat envious of the simplicity that comes from the blocking solutions.

The DBus values I'm querying are essentially a conversion of a snippet from the python found here, i.e. grab the "ValidAccounts" from "org.freedesktop.Telepathy.AccountManager", then for each object path in the resulting list of accounts, grab the "Enabled" property.

The mess of multiple callbacks however makes me sad, as it makes the flow very difficult to follow. It also took me several hours before I realised the reason I wasn't getting anything back was because I wasn't running the glib main loop.

For context, this is a tiny console app I'm using to develop this section of functionality before I move it across into the main GUI app. Hence my initial confusion at needing an event loop....(and because of the event loop I still haven't found a decent way of terminating the thing when it's finished executing....even before I realised I couldn't tell when all my callbacks were complete).

So I guess the tracking the manually tracking counts of things aka. book-keeping is the way forward. A shame, I was kinda hoping for another callback for "all done".
 
epage's Avatar
Posts: 1,684 | Thanked: 1,562 times | Joined on Jun 2008 @ Austin, TX
#4
Originally Posted by mr_jrt View Post
Thanks for the reply. I appreciate your point with the thread title....changed

Python's next on my to-learn list...the python dbus examples I've stumbled across have all used nice blocking code in them, which makes me somewhat envious of the simplicity that comes from the blocking solutions.

The DBus values I'm querying are essentially a conversion of a snippet from the python found here, i.e. grab the "ValidAccounts" from "org.freedesktop.Telepathy.AccountManager", then for each object path in the resulting list of accounts, grab the "Enabled" property.

The mess of multiple callbacks however makes me sad, as it makes the flow very difficult to follow. It also took me several hours before I realised the reason I wasn't getting anything back was because I wasn't running the glib main loop.

For context, this is a tiny console app I'm using to develop this section of functionality before I move it across into the main GUI app. Hence my initial confusion at needing an event loop....(and because of the event loop I still haven't found a decent way of terminating the thing when it's finished executing....even before I realised I couldn't tell when all my callbacks were complete).

So I guess the tracking the manually tracking counts of things aka. book-keeping is the way forward. A shame, I was kinda hoping for another callback for "all done".
Synchronous API, for any language or binding, is discouraged. The upside is that python has some powerful language constructs to keep callback management clean
https://github.com/epage/DialCentral...src/session.py
(Any function with a "yield" is basically saying "perform this op and then run the rest of the function in a callback)

No matter what you have to do book keeping as telepathy would have no idea what "done" would be. Now you can construct your code to keep it as simple by having very special built classes similar to what I did in my python files I sent you.
__________________
770, n810, n900, Ideapad S10-3t
TheOneRing, DialCentral, Gonvert, Quicknote, Multilist, ejpi, nQa, Waters of Shiloah
Programming Blog
 
Posts: 249 | Thanked: 277 times | Joined on May 2010 @ Brighton, UK
#5
Given that I don't really care about anything from telepathy other than property twiddling, I decided to try alternate ways of working with DBus, and am quite happy with Qt's QtDBus API.

I've got this now (I've used the PHP markup for the highlighting):
PHP Code:
#include <QtDBus/QtDBus>

#include <QDebug>
#include <QtCore/QCoreApplication>

#include <telepathy-glib/interfaces.h>

const char TP_PATH_ACCOUNT_MANAGER("/org/freedesktop/Telepathy/AccountManager");

int main(int argcchar *argv[])
{
    
QCoreApplication a(argcargv);

    
QDBusInterface tpAccountManagerApp(
        
TP_IFACE_ACCOUNT_MANAGER,
        
TP_PATH_ACCOUNT_MANAGER,
        
TP_IFACE_DBUS_PROPERTIES);

    if (
tpAccountManagerApp.isValid())
    {
        
QDBusMessage accountList tpAccountManagerApp.call(
            
"Get",
            
TP_IFACE_ACCOUNT_MANAGER,
            
"ValidAccounts");
        foreach (
QVariant argaccountList.arguments())
        {
            
QDBusArgument argument(qvariant_cast<QDBusVariant>(arg).variant().value<QDBusArgument>());
            
argument.beginArray();
            while (!
argument.atEnd())
            {
                
// Grab the account path
                
QDBusObjectPath objectPath;
                
argument >> objectPath;

                
//Grab the enabled property of each account
                
QDBusInterface tpAccount(
                    
TP_IFACE_ACCOUNT_MANAGER,
                    
objectPath.path(),
                    
TP_IFACE_DBUS_PROPERTIES);
                if (
tpAccount.isValid())
                {
                    
QDBusReply<QVariantisEnabledProp tpAccount.call(
                        
"Get",
                        
TP_IFACE_ACCOUNT,
                        
"Enabled");
                    
qDebug() << (isEnabledProp.value().toBool() ? "Enabled:\t\t" "Not enabled:\t") << objectPath.path();
                }
            }
            
argument.endArray();
        }
    }

    return 
a.exec();

...but get a weird warning that I'm going to treat as an error:
Code:
Enabled:		 "/org/freedesktop/Telepathy/Account/ring/tel/ring" 
Not enabled:	 "/org/freedesktop/Telepathy/Account/gabble/jabber/jamierocks_40gmail_2ecom0" 
Enabled:		 "/org/freedesktop/Telepathy/Account/sofiasip/sip/_373023190" 
Not enabled:	 "/org/freedesktop/Telepathy/Account/sofiasip/sip/_33888389_40sipgate_2eco_2euk0" 
Not enabled:	 "/org/freedesktop/Telepathy/Account/gabble/jabber/jamie_40jabber_2ejamie_2dthompson_2eco_2euk0" 
Not enabled:	 "/org/freedesktop/Telepathy/Account/gabble/jabber/qwerki_40chat_2efacebook_2ecom0" 
QDBusArgument: write from a read-only object
...this comes from the call to "argument.endArray();". The error goes away when I remove the call, but the documentation says it's required to match up with the call to "argument.beginArray();".

Something new to ponder, though I'll happily take any answers anyone has to offer
 
Posts: 249 | Thanked: 277 times | Joined on May 2010 @ Brighton, UK
#6
...and the correct answer is...to make the QDBusArgument const.
 

The Following User Says Thank You to mr_jrt For This Useful Post:
Reply


 
Forum Jump


All times are GMT. The time now is 13:43.