telepathyClient: No need to prepare channel contacts

tp-glib does it for us since version 0.15.6

https://bugzilla.gnome.org/show_bug.cgi?id=658817
This commit is contained in:
Xavier Claessens 2011-09-12 14:33:02 +02:00 committed by Xavier Claessens
parent 41f6956197
commit 5cf06fe9a7
4 changed files with 21 additions and 207 deletions

View File

@ -70,7 +70,7 @@ GIO_MIN_VERSION=2.31.0
LIBECAL_MIN_VERSION=2.32.0 LIBECAL_MIN_VERSION=2.32.0
LIBEDATASERVER_MIN_VERSION=1.2.0 LIBEDATASERVER_MIN_VERSION=1.2.0
LIBEDATASERVERUI_MIN_VERSION=2.91.6 LIBEDATASERVERUI_MIN_VERSION=2.91.6
TELEPATHY_GLIB_MIN_VERSION=0.15.5 TELEPATHY_GLIB_MIN_VERSION=0.15.6
TELEPATHY_LOGGER_MIN_VERSION=0.2.4 TELEPATHY_LOGGER_MIN_VERSION=0.2.4
POLKIT_MIN_VERSION=0.100 POLKIT_MIN_VERSION=0.100
STARTUP_NOTIFICATION_MIN_VERSION=0.11 STARTUP_NOTIFICATION_MIN_VERSION=0.11

View File

@ -33,10 +33,6 @@ const NotificationDirection = {
RECEIVED: 'chat-received' RECEIVED: 'chat-received'
}; };
let contactFeatures = [Tp.ContactFeature.ALIAS,
Tp.ContactFeature.AVATAR_DATA,
Tp.ContactFeature.PRESENCE];
// This is GNOME Shell's implementation of the Telepathy 'Client' // This is GNOME Shell's implementation of the Telepathy 'Client'
// interface. Specifically, the shell is a Telepathy 'Observer', which // interface. Specifically, the shell is a Telepathy 'Observer', which
// lets us see messages even if they belong to another app (eg, // lets us see messages even if they belong to another app (eg,
@ -83,11 +79,21 @@ const Client = new Lang.Class({
// account path -> AccountNotification // account path -> AccountNotification
this._accountNotifications = {}; this._accountNotifications = {};
// Define features we want
this._accountManager = Tp.AccountManager.dup();
let factory = this._accountManager.get_factory();
factory.add_account_features([Tp.Account.get_feature_quark_connection()]);
factory.add_connection_features([Tp.Connection.get_feature_quark_contact_list()]);
factory.add_channel_features([Tp.Channel.get_feature_quark_contacts()]);
factory.add_contact_features([Tp.ContactFeature.ALIAS,
Tp.ContactFeature.AVATAR_DATA,
Tp.ContactFeature.PRESENCE,
Tp.ContactFeature.SUBSCRIPTION_STATES]);
// Set up a SimpleObserver, which will call _observeChannels whenever a // Set up a SimpleObserver, which will call _observeChannels whenever a
// channel matching its filters is detected. // channel matching its filters is detected.
// The second argument, recover, means _observeChannels will be run // The second argument, recover, means _observeChannels will be run
// for any existing channel as well. // for any existing channel as well.
this._accountManager = Tp.AccountManager.dup();
this._tpClient = new Shell.TpClient({ 'account-manager': this._accountManager, this._tpClient = new Shell.TpClient({ 'account-manager': this._accountManager,
'name': 'GnomeShell', 'name': 'GnomeShell',
'uniquify-name': true }) 'uniquify-name': true })
@ -114,16 +120,9 @@ const Client = new Lang.Class({
throw new Error('Couldn\'t register Telepathy client. Error: \n' + e); throw new Error('Couldn\'t register Telepathy client. Error: \n' + e);
} }
// Watch subscription requests and connection errors // Watch subscription requests and connection errors
this._subscriptionSource = null; this._subscriptionSource = null;
this._accountSource = null; this._accountSource = null;
let factory = this._accountManager.get_factory();
factory.add_account_features([Tp.Account.get_feature_quark_connection()]);
factory.add_connection_features([Tp.Connection.get_feature_quark_contact_list()]);
factory.add_contact_features([Tp.ContactFeature.SUBSCRIPTION_STATES,
Tp.ContactFeature.ALIAS,
Tp.ContactFeature.AVATAR_DATA]);
this._accountManager.connect('account-validity-changed', this._accountManager.connect('account-validity-changed',
Lang.bind(this, this._accountValidityChanged)); Lang.bind(this, this._accountValidityChanged));
@ -133,22 +132,6 @@ const Client = new Lang.Class({
_observeChannels: function(observer, account, conn, channels, _observeChannels: function(observer, account, conn, channels,
dispatchOp, requests, context) { dispatchOp, requests, context) {
// If the self_contact doesn't have the ALIAS, make sure
// to fetch it before trying to grab the channels.
let self_contact = conn.get_self_contact();
if (self_contact.has_feature(Tp.ContactFeature.ALIAS)) {
this._finishObserveChannels(account, conn, channels, context);
} else {
Shell.get_self_contact_features(conn,
contactFeatures,
Lang.bind(this, function() {
this._finishObserveChannels(account, conn, channels, context);
}));
context.delay();
}
},
_finishObserveChannels: function(account, conn, channels, context) {
let len = channels.length; let len = channels.length;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
let channel = channels[i]; let channel = channels[i];
@ -159,16 +142,7 @@ const Client = new Lang.Class({
targetHandleType != Tp.HandleType.CONTACT) targetHandleType != Tp.HandleType.CONTACT)
continue; continue;
/* Request a TpContact */ this._createChatSource(account, conn, channel, channel.get_target_contact());
Shell.get_tp_contacts(conn, [targetHandle],
contactFeatures,
Lang.bind(this, function (connection, contacts, failed) {
if (contacts.length < 1)
return;
/* We got the TpContact */
this._createChatSource(account, conn, channel, contacts[0]);
}), null);
} }
context.accept(); context.accept();
@ -234,41 +208,25 @@ const Client = new Lang.Class({
_displayRoomInvitation: function(conn, channel, dispatchOp, context) { _displayRoomInvitation: function(conn, channel, dispatchOp, context) {
// We can only approve the rooms if we have been invited to it // We can only approve the rooms if we have been invited to it
let selfHandle = channel.group_get_self_handle(); let selfContact = channel.group_get_self_contact();
if (selfHandle == 0) { if (selfContact == null) {
Shell.decline_dispatch_op(context, 'Not invited to the room'); Shell.decline_dispatch_op(context, 'Not invited to the room');
return; return;
} }
let [invited, inviter, reason, msg] = channel.group_get_local_pending_info(selfHandle); let [invited, inviter, reason, msg] = channel.group_get_local_pending_contact_info(selfContact);
if (!invited) { if (!invited) {
Shell.decline_dispatch_op(context, 'Not invited to the room'); Shell.decline_dispatch_op(context, 'Not invited to the room');
return; return;
} }
// Request a TpContact for the inviter
Shell.get_tp_contacts(conn, [inviter],
contactFeatures,
Lang.bind(this, this._createRoomInviteSource, channel, context, dispatchOp));
context.delay();
},
_createRoomInviteSource: function(connection, contacts, failed, channel, context, dispatchOp) {
if (contacts.length < 1) {
Shell.decline_dispatch_op(context, 'Failed to get inviter');
return;
}
// We got the TpContact
// FIXME: We don't have a 'chat room' icon (bgo #653737) use // FIXME: We don't have a 'chat room' icon (bgo #653737) use
// system-users for now as Empathy does. // system-users for now as Empathy does.
let source = new ApproverSource(dispatchOp, _("Invitation"), let source = new ApproverSource(dispatchOp, _("Invitation"),
Gio.icon_new_for_string('system-users')); Gio.icon_new_for_string('system-users'));
Main.messageTray.add(source); Main.messageTray.add(source);
let notif = new RoomInviteNotification(source, dispatchOp, channel, contacts[0]); let notif = new RoomInviteNotification(source, dispatchOp, channel, inviter);
source.notify(notif); source.notify(notif);
context.accept(); context.accept();
}, },
@ -308,21 +266,6 @@ const Client = new Lang.Class({
}, },
_approveCall: function(account, conn, channel, dispatchOp, context) { _approveCall: function(account, conn, channel, dispatchOp, context) {
let [targetHandle, targetHandleType] = channel.get_handle();
Shell.get_tp_contacts(conn, [targetHandle],
contactFeatures,
Lang.bind(this, this._createAudioVideoSource, channel, context, dispatchOp));
context.delay();
},
_createAudioVideoSource: function(connection, contacts, failed, channel, context, dispatchOp) {
if (contacts.length < 1) {
Shell.decline_dispatch_op(context, 'Failed to get inviter');
return;
}
let isVideo = false; let isVideo = false;
let props = channel.borrow_immutable_properties(); let props = channel.borrow_immutable_properties();
@ -337,27 +280,13 @@ const Client = new Lang.Class({
Gio.icon_new_for_string('audio-input-microphone')); Gio.icon_new_for_string('audio-input-microphone'));
Main.messageTray.add(source); Main.messageTray.add(source);
let notif = new AudioVideoNotification(source, dispatchOp, channel, contacts[0], isVideo); let notif = new AudioVideoNotification(source, dispatchOp, channel,
channel.get_target_contact(), isVideo);
source.notify(notif); source.notify(notif);
context.accept(); context.accept();
}, },
_approveFileTransfer: function(account, conn, channel, dispatchOp, context) { _approveFileTransfer: function(account, conn, channel, dispatchOp, context) {
let [targetHandle, targetHandleType] = channel.get_handle();
Shell.get_tp_contacts(conn, [targetHandle],
contactFeatures,
Lang.bind(this, this._createFileTransferSource, channel, context, dispatchOp));
context.delay();
},
_createFileTransferSource: function(connection, contacts, failed, channel, context, dispatchOp) {
if (contacts.length < 1) {
Shell.decline_dispatch_op(context, 'Failed to get file sender');
return;
}
// Use the icon of the file being transferred // Use the icon of the file being transferred
let gicon = Gio.content_type_get_icon(channel.get_mime_type()); let gicon = Gio.content_type_get_icon(channel.get_mime_type());
@ -365,7 +294,8 @@ const Client = new Lang.Class({
let source = new ApproverSource(dispatchOp, _("File Transfer"), gicon); let source = new ApproverSource(dispatchOp, _("File Transfer"), gicon);
Main.messageTray.add(source); Main.messageTray.add(source);
let notif = new FileTransferNotification(source, dispatchOp, channel, contacts[0]); let notif = new FileTransferNotification(source, dispatchOp, channel,
channel.get_target_contact());
source.notify(notif); source.notify(notif);
context.accept(); context.accept();
}, },

View File

@ -340,104 +340,6 @@ shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
/* Telepathy utility functions */ /* Telepathy utility functions */
/**
* ShellGetTpContactCb:
* @connection: The connection
* @contacts: (element-type TelepathyGLib.Contact): List of contacts
* @failed: Array of failed contacts
*/
static void
shell_global_get_tp_contacts_cb (TpConnection *self,
guint n_contacts,
TpContact * const *contacts,
guint n_failed,
const TpHandle *failed,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
int i;
GList *contact_list = NULL;
for (i = 0; i < n_contacts; i++) {
contact_list = g_list_append(contact_list, contacts[i]);
}
TpHandle *failed_list = g_new0 (TpHandle, n_failed + 1);
memcpy(failed_list, failed, n_failed);
((ShellGetTpContactCb)user_data)(self, contact_list, failed_list);
}
/**
* shell_get_tp_contacts:
* @self: A connection, which must be ready
* @n_handles: Number of handles in handles
* @handles: (array length=n_handles) (element-type uint): Array of handles
* @n_features: Number of features in features
* @features: (array length=n_features) (allow-none) (element-type uint):
* Array of features
* @callback: (scope async): User callback to run when the contacts are ready
*
* Wrap tp_connection_get_contacts_by_handle so we can transform the array
* into a null-terminated one, which gjs can handle.
* We send the original callback to tp_connection_get_contacts_by_handle as
* user_data, and we have our own function as callback, which does the
* transforming.
*/
void
shell_get_tp_contacts (TpConnection *self,
guint n_handles,
const TpHandle *handles,
guint n_features,
const TpContactFeature *features,
ShellGetTpContactCb callback)
{
tp_connection_get_contacts_by_handle(self, n_handles, handles,
n_features, features,
shell_global_get_tp_contacts_cb,
callback, NULL, NULL);
}
static void
shell_global_get_self_contact_features_cb (TpConnection *connection,
guint n_contacts,
TpContact * const *contacts,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
if (error != NULL) {
g_print ("Failed to upgrade self contact: %s", error->message);
return;
}
((ShellGetSelfContactFeaturesCb)user_data)(connection, *contacts);
}
/**
* shell_get_self_contact_features:
* @self: A connection, which must be ready
* @n_features: Number of features in features
* @features: (array length=n_features) (allow-none) (element-type uint):
* Array of features
* @callback: (scope async): User callback to run when the contact is ready
*
* Wrap tp_connection_upgrade_contacts due to the lack of support for
* proper arrays arguments in GJS.
*/
void
shell_get_self_contact_features (TpConnection *self,
guint n_features,
const TpContactFeature *features,
ShellGetSelfContactFeaturesCb callback)
{
TpContact *self_contact = tp_connection_get_self_contact (self);
tp_connection_upgrade_contacts (self, 1, &self_contact,
n_features, features,
shell_global_get_self_contact_features_cb,
callback, NULL, NULL);
}
/** /**
* shell_get_contact_events: * shell_get_contact_events:

View File

@ -102,24 +102,6 @@ void shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
TpConnection *conn); TpConnection *conn);
/* Telepathy utility functions */ /* Telepathy utility functions */
typedef void (*ShellGetTpContactCb) (TpConnection *connection,
GList *contacts,
TpHandle *failed);
void shell_get_tp_contacts (TpConnection *self,
guint n_handles,
const TpHandle *handles,
guint n_features,
const TpContactFeature *features,
ShellGetTpContactCb callback);
typedef void (*ShellGetSelfContactFeaturesCb) (TpConnection *connection,
TpContact *contact);
void shell_get_self_contact_features (TpConnection *self,
guint n_features,
const TpContactFeature *features,
ShellGetSelfContactFeaturesCb callback);
void shell_get_contact_events (TplLogManager *log_manager, void shell_get_contact_events (TplLogManager *log_manager,
TpAccount *account, TpAccount *account,