It is a common case to need to get the TpAccount object from a TpContact. The work flow is usually: You have an object 'self' which needs to work with contacts: 1) Get a TpAccount 2) Gets its TpConnection, and wait for it to be ready. You have only one user_data so you give self 3) Get some TpContact from the connection 4) ... You need the TpAccount of that contact, but since the only user_data you had for step 2 is self, you "lost" the account pointer. The usual solutions for that is to use g_object_set_data(connection, "account", account); or create a struct{self, account}; to pass as user_data. It is ugly and complex for a very common flow IMO. So I suggest adding a TpConnection:account construct-only property. When TpAccount creates its own TpConnection object, that property is set. If the TpConnection is created manually, that property is defined as NULL. Like that we are sure to keep a 1:1 mapping TpAccount<>TpConnection.
We've discussed this on IRC and not really come to a conclusion; there are some problems with a naive approach, like reference-counting cycles between the account and connection. In Handlers and similar channel-oriented things, we shouldn't generally need this, because there'll usually be an object (e.g. an Empathy chat tab) that knows its own account, connection and channel. The difficult case is when you have a contact but you're not account- or channel-specific, like the Empathy contact list owning TpContact objects, and wanting to know which account to pass to ChannelDispatcher.EnsureChannel when you click on a contact. The contact list is account-agnostic, although I think we can safely assume it has a ref to the TpAccountManager. 10:48 < Zdra> smcv, the use case is: "I have a TpContact and I want to request a channel for it", the dispatcher needs the account 10:48 < smcv> devil's advocate: isn't that just an artefact of us not having metacontacts yet? Some possibilities: What Zdra proposed in Comment #0 ================================ 10:50 < smcv> the correct form of "they each ref the other" would be that the Connection releases its ref when invalidated 10:50 < smcv> or soemthing We could have: TpAccount refs TpConnection until the TpConnection is invalidated. TpConnection refs TpAccount. 10:43 < smcv> I don't think adding a property whose value might be a lie is the right solution 10:43 < danni> smcv: well it's either real or NULL 10:43 < danni> and we can define the semantics by which it will be real or NULL 10:43 < smcv> right, but the NULL case means "either it doesn't belong to an account or I have no idea" ... 10:44 < danni> smcv: if we define the semantics, the programmer will know whether she expects it to be null or not ... 10:55 < smcv> the relationship isn't strictly 1:1, which is an extra wart 10:56 < smcv> if you keep hold of refs to a dead TpConnection, then they still belong to the same Account you first thought of, but are not the *current* Connection for that Account Global lookup table =================== Rejected: 10:43 < Zdra> smcv, danni: what about TpAccount *tp_account_lookup_for_connection(TpConnection){return g_hash_table_lookup (global_conn_to_acc_table, connection);} 10:44 < Zdra> hm, nevermind, that's just the same has having prop on the conn Connection knows the *object path of* its Account ================================================= This has the same issues as Comment #0 in terms of not always having the necessary information, but unlike Comment #0, it doesn't have cyclic references. 10:57 < smcv> one way to not have the ref cycle would be for the TpConnection to know its own Account *by object path* ... 11:04 < smcv> you can emulate tp_am_ensure with tp_account_ensure (tp_am_ensure_account (am, path), ...) in any case Ability to look up the account for a connection in the TpAM =========================================================== telepathy-qt4 has something quite similar to this. 10:32 < wjt> add a method to the AM to get the A for a Conn 10:33 < wjt> see also, the Tp::AccountSet API in tp-qt4 10:36 < Zdra> smcv, do you prefer something like this? tp_account_manager_get_account_for_connection(connection){for (all accounts) if (account.connection == connection) return account;} ? 10:36 < danni> the problem is if you have multiple account proxies/connection proxies, it gets messy 10:36 < danni> which one do you mean 10:37 < smcv> danni: the one the AM has in tp_account_manager_get_valid_accounts() 10:37 < smcv> danni: for bonus penguin points match by object path instead of by identity :-) ... 10:40 < danni> smcv: also, now you have to prepare more stuff, which you really don't care about
*** Bug 30185 has been marked as a duplicate of this bug. ***
I have a simple patch for this: http://cgit.collabora.com/git/user/xclaesse/telepathy-glib.git/commit/?h=contact-list&id=e0ffadae465be3dad4125119f28cee096f14b2c5 I think that's already a first step. In the future we could use a ProxyFactory that guarantee uniqueness of TpConnection objects, so if TpAccount uses the same factory as the user used to get its TpConnection, that would guarantee the account is set too.
It sounds a bit weird to me to have API working only if the TpConnection has been retrieved in a specific way. For example, would it work with the TpConnection received from TpBaseClient's callbacks? User just don't know.
Since TpConnection is a CM proxy and TpAccount is a MC proxy, there is just no way a TpConnection get always guarantee to know its TpAccount. The best we can do is guarantee that if a TpAccountManager happens to be prepared, then TpConnection objects shared by an account will have the account set. That's what my branch does. A 2nd step, would make sure that TpAccount and TpBaseClient actually share the same TpConnection objects, but for that we need a factory that creates unique proxies, like we have (or will have?) for TpChannel. Once that 2nd step is done, that will become "Your connection has an account if and only if a TpAccount exists and is using the same connection factory than your TpBaseClient".
Merged as part of work on bug #38142. Now if a TpAccount lives within the same factory than its TpConnection, then tp_connection_get_account() will return it.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.