/** * demo usage pattern of telepathy-qt API * * @author izicochang@gmail.com * @since 5/23/2007 */ #include "test.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "QtTelepathy/Client/ChannelMediaSignallingInterface" #include "QtTelepathy/Client/MediaSessionHandler" #include "QtTelepathy/Client/MediaStreamHandler" #include #include using namespace org::freedesktop::Telepathy; /** * all types used in DBus communication must be registered to Qt's metatype * object system to use Qt's covenience */ static void registerTypes() { static bool registered = false; if (!registered) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); registered = true; } } static void signal_handler(int) { QCoreApplication::instance()->quit(); } /** * install the thread-unsafe signal handler for convenience in studying */ static bool install_signal_handlers() { if (SIG_ERR == signal(SIGINT, signal_handler)) { qDebug() << "can't install signal handler for SIGINT."; return false; } if (SIG_ERR == signal(SIGHUP, signal_handler)) { qDebug() << "can't install signal handler for SIGHUP."; return false; } if (SIG_ERR == signal(SIGQUIT, signal_handler)) { qDebug() << "can't install signal handler for SIGQUIT."; return false; } if (SIG_ERR == signal(SIGABRT, signal_handler)) { qDebug() << "can't install signal handler for SIGABRT."; return false; } if (SIG_ERR == signal(SIGTERM, signal_handler)) { qDebug() << "can't install signal handler for SIGTERM."; return false; } return true; } /** * get account information from command line * * @param argc in cmdline * @param argv in cmdline * @param protocol out protocol for CM * @param cmService inout service for CM * @param cmObjPath inout object path for CM * @param accountParam out account parameters for CM * * @return bool if valid account parameters are returned */ static bool get_account_info(int argc, char* argv[], QString& protocol, QString& cmService, QDBusObjectPath& cmObjPath, QVariantMap& accountParam) { if (argc < 4) { qDebug() << "Usage: test protocol user@host password [server port]"; return false; } protocol = argv[1]; // set account parameters if ("jabber" == protocol) { if (QString(argv[2]).endsWith("@gmail.com") || QString(argv[2]).endsWith("@googlemail.com")) { accountParam["server"] = QVariant("talk.google.com"); accountParam["old-ssl"] = QVariant(true); accountParam["ignore-ssl-errors"] = QVariant(true); accountParam["port"] = QVariant((uint) 5223); accountParam["stun-server"] = QVariant("stun.l.google.com"); } else { if (argc < 6) { qDebug() << "usage: test protocol username@host password" << "server port"; return false; } accountParam["server"] = QVariant(argv[4]); accountParam["port"] = QVariant(QString(argv[5]).toUInt()); } cmService += ".gabble"; cmObjPath.setPath(cmObjPath.path() + "/gabble"); } else if ("sip" == protocol) { if (argc > 4) { accountParam["registrar"] = QVariant(argv[4]); } if (argc > 5) { accountParam["port"] = QVariant(QString(argv[5]).toUInt()); } cmService += ".sofiasip"; cmObjPath.setPath(cmObjPath.path() + "/sofiasip"); } else if ("msn" == protocol) { cmService += ".butterfly"; cmObjPath.setPath(cmObjPath.path() + "/butterfly"); } else if ("irc" == protocol) { cmService += ".idle"; cmObjPath.setPath(cmObjPath.path() + "/idle"); } else { qDebug() << "protocol " << protocol << " is not supported yet."; return false; } accountParam["account"] = QVariant(argv[2]); accountParam["password"] = QVariant(argv[3]); return true; } /** * create the CM * * @param protocol in * @param service in * @param objPath in * @param mf inout */ static void init_connection_manager(const QString& protocol, const QString& service, const QString& objPath, MessageFilter& mf) { mf.cm = new ConnectionManager(service, objPath, mf.bus, &mf); // get the parameters supported on this connection manager for this protocol QDBusReply cmParams = mf.cm->GetParameters(protocol); if (!cmParams.isValid()) { qDebug() << "GetParameters() returned error:" << cmParams.error().name() << cmParams.error().message() << "\n"; } else { qDebug() << "Supported parameters of protocol" << protocol << ":"; foreach (org::freedesktop::Telepathy::ParameterDefinition param, cmParams.value()) { qDebug() << "\tname:" << param.name << "\n\tflags:" << param.flags << "\n\tD-Bus type signature:" << param.signature << "\n\tdefault value:" << param.defaultValue.variant() << "\n"; } } // list all the protocols supported by the CM QDBusReply protocols = mf.cm->ListProtocols(); if (!protocols.isValid()) { qDebug() << "ListProtocols() returned error:" << protocols.error().name() << protocols.error().message() << "\n"; } else { qDebug() << "Supported protocols of the CM:" << protocols.value() << "\n"; } // catch all the signals emited by CM QObject::connect(mf.cm, SIGNAL(NewConnection(QString, QDBusObjectPath, QString)), &mf, SLOT(onNewConnection(QString, QDBusObjectPath, QString))); } /** * create the connection to the remote server * * @param protocol in protocol for the connection * @param accountParam in account parameters for the connection * @param connService out DBus service of the connection * @param connObjPath out DBus object path of the connection * @param mf inout * * @return bool if connection is created successfully */ static bool init_connection(const QString& protocol, const QVariantMap accountParam, QString& connService, QDBusObjectPath& connObjPath, MessageFilter& mf) { QDBusReply connServiceName = mf.cm->RequestConnection(protocol, accountParam, connObjPath); if (!connServiceName.isValid()) { qDebug() << "RequestConnection() returned error:" << connServiceName.error().name() << connServiceName.error().message(); return false; } else { connService = connServiceName.value(); qDebug() << "connection is created on:" << "\n\tservice:" << connService << "\n\tobject path:" << connObjPath.path() << "\n"; } mf.conn = new Connection(connService, connObjPath.path(), mf.bus, &mf); // catch all the signals emited on this connection QObject::connect(mf.conn, SIGNAL(StatusChanged(uint,uint)), &mf, SLOT(OnStatusChanged(uint,uint))); QObject::connect(mf.conn, SIGNAL(NewChannel(QDBusObjectPath, QString, uint, uint, bool)), &mf, SLOT(onNewChannel(QDBusObjectPath, QString, uint, uint, bool))); return true; } /** * create the aliasing interface of the connection * * @param service in * @param objPath in * @param mf inout */ static void init_connection_interface_aliasing(const QString& service, const QDBusObjectPath& objPath, MessageFilter& mf) { mf.aliasingIface = new ConnectionAliasingInterface(service, objPath.path(), mf.bus, &mf); // catch all the signals emited on aliasing interface QObject::connect(mf.aliasingIface, SIGNAL(AliasesChanged(org::freedesktop::Telepathy:: AliasInfoList)), &mf, SLOT(onAliasesChanged(org::freedesktop::Telepathy:: AliasInfoList))); } /** * create the avatars interface of the connection * * @param service in * @param objPath in * @param mf inout */ static void init_connection_interface_avatars(const QString& service, const QDBusObjectPath& objPath, MessageFilter& mf) { mf.avatarsIface = new ConnectionAvatarsInterface(service, objPath.path(), mf.bus, &mf); // catch all signals emited on avatar interface QObject::connect(mf.avatarsIface, SIGNAL(AvatarUpdated(uint, QString)), &mf, SLOT(onAvatarUpdated(uint, QString))); } static void init_connection_interface_capabilities(const QString& service, const QDBusObjectPath& objPath, MessageFilter& mf) { mf.capabilitiesIface = new ConnectionCapabilitiesInterface(service, objPath.path(), mf.bus, &mf); // catch all the signals QObject::connect(mf.capabilitiesIface, SIGNAL(CapabilitiesChanged(org::freedesktop::Telepathy::CapabilitiesChangedInfoList)), &mf, SLOT(onCapabilitiesChanged(org::freedesktop::Telepathy::CapabilitiesChangedInfoList))); } static void init_connection_interface_forwarding(const QString& service, const QDBusObjectPath& objPath, MessageFilter& mf) { mf.forwardingIface = new ConnectionForwardingInterface(service, objPath.path(), mf.bus, &mf); QObject::connect(mf.forwardingIface, SIGNAL(ForwardingChanged(uint)), &mf, SLOT(onForwardingChanged(uint))); } static void init_connection_interface_presence(const QString& service, const QDBusObjectPath& objPath, MessageFilter& mf) { mf.presenceIface = new ConnectionPresenceInterface(service, objPath.path(), mf.bus, &mf); QObject::connect(mf.presenceIface, SIGNAL(PresenceUpdate(org::freedesktop::Telepathy::PresenceStateInTimeMap)), &mf, SLOT(onPresenceUpdate(org::freedesktop::Telepathy::PresenceStateInTimeMap))); } static void init_connection_interface_privacy(const QString& service, const QDBusObjectPath& objPath, MessageFilter& mf) { mf.privacyIface = new ConnectionPrivacyInterface(service, objPath.path(), mf.bus, &mf); QObject::connect(mf.privacyIface, SIGNAL(PrivacyModeChanged(QString)), &mf, SLOT(onPrivacyModeChanged(QString))); } static void init_connection_interface_renaming(const QString& service, const QDBusObjectPath& objPath, MessageFilter& mf) { mf.renamingIface = new ConnectionRenamingInterface(service, objPath.path(), mf.bus, &mf); QObject::connect(mf.renamingIface, SIGNAL(Renamed(uint, uint)), &mf, SLOT(onRenamed(uint, uint))); } int main(int argc, char **argv) { // get the account parameters from command line QString protocol; QString cmService("org.freedesktop.Telepathy.ConnectionManager"); QDBusObjectPath cmObjPath("/org/freedesktop/Telepathy/ConnectionManager"); QVariantMap accountParam; if (!get_account_info(argc, argv, protocol, cmService, cmObjPath, accountParam)) { return -1; } // install signal handlers for convenience in testing if (!install_signal_handlers()) { return -1; } QCoreApplication app(argc, argv); // register types for DBus marshall/demashall, all types used in DBus // communiction should be registered(method_call,signal,method_return, // error), otherwise there's type signature mismatch problem registerTypes(); // connect to DBus session bus if (!QDBusConnection::sessionBus().isConnected()) { qDebug() << "Cannot connect to the D-BUS session bus.\n" "To start it, run:\n" "\teval `dbus-launch --auto-syntax`\n"; return -1; } // create the message filter MessageFilter mf(QDBusConnection::sessionBus(), &app); // create the connection manager init_connection_manager(protocol, cmService, cmObjPath.path(), mf); // request a connection to the server QString connService; QDBusObjectPath connObjPath; if (!init_connection(protocol, accountParam, connService, connObjPath, mf)) { return -1; } // get the aliasing interface of this connection init_connection_interface_aliasing(connService, connObjPath, mf); // get the avatar interface of the connection init_connection_interface_avatars(connService, connObjPath, mf); // get the capabilities interface of the connection init_connection_interface_capabilities(connService, connObjPath, mf); // get the forwarding interface of the connection init_connection_interface_forwarding(connService, connObjPath, mf); // get the presence interface of the connection init_connection_interface_presence(connService, connObjPath, mf); // get the privacy interface of the connection init_connection_interface_privacy(connService, connObjPath, mf); // get the renaming interface of the connection init_connection_interface_renaming(connService, connObjPath, mf); // connect to the remote server to be online now mf.conn->Connect(); return app.exec(); } MessageFilter::MessageFilter(const QDBusConnection &b, QObject *parent) : QObject(parent), bus(b) { cm = 0; conn = 0; aliasingIface = 0; avatarsIface = 0; capabilitiesIface = 0; forwardingIface = 0; presenceIface = 0; privacyIface = 0; renamingIface = 0; } MessageFilter::~MessageFilter() { // disconnect the connection if it's still in use to release the CM if (conn) { conn->Disconnect(); } } /** * A new connection is opened by the CM * * @param service * @param objPath * @param proto */ void MessageFilter::onNewConnection(const QString& service, const QDBusObjectPath& objPath, const QString& proto) { qDebug() << "new connection has been created on:" << "\n\tservice:" << service << "\n\tpath:" << objPath.path() << "\n\tprotocol:" << proto << "\n"; } /** * a new channel has been opened on the connection * * @param objPath * @param channelType * @param handleType * @param handle * @param suppressHandler */ void MessageFilter::onNewChannel(const QDBusObjectPath& objPath, const QString& channelType, uint handleType, uint handle, bool suppressHandler) { qDebug() << "new channel has been opened:" << "\n\tobject path:" << objPath.path() << "\n\tchannel type:" << channelType << "\n\thandle type:" << handleType << "\n\thandle:" << handle; if (handle) { QDBusReply handleName = conn->InspectHandles(handleType, QList() << handle); if (!handleName.isValid()) { qDebug() << "InspectHandles() returned error:" << handleName.error().name() << handleName.error().message() << "\n"; } else { qDebug() << "\thandle name:" << handleName.value(); } } qDebug() << "\tsuppress handler:" << suppressHandler << "\n"; // accept streamed media call if (("org.freedesktop.Telepathy.Channel.Type.StreamedMedia" == channelType) && (!suppressHandler)) { setupStreamedMediaChannel(objPath); // the contact is in local pending list now QDBusReply > localPendingMemberHandleList = smChannelGroupIface->GetLocalPendingMembers(); if (!localPendingMemberHandleList.isValid()) { qDebug() << "GetLocalPendingMembers() returned error:" << localPendingMemberHandleList.error().name() << localPendingMemberHandleList.error().message() << "\n"; return; } if (localPendingMemberHandleList.value().isEmpty()) { qDebug() << "GetLocalPendingMembers() should not return 0 user.\n"; return; } qDebug() << "local pending members:" << localPendingMemberHandleList.value() << "\n"; QDBusReply reply = smChannelGroupIface->AddMembers(localPendingMemberHandleList.value(), ""); if (!reply.isValid()) { qDebug() << "AddMembers() returned error:" << reply.error().name() << reply.error().message() << "\n"; return; } smContactHandle = 0; smContactCapabilies = 0; #if 0 bool isContactCapableOfStreamedMedia = false; /* if we come here too quickly, the capability changed signal of the contact has not been received, so it'll fail to find the streamed media capability of the contact */ // get the capabilities of the contact QDBusReply contactCapabilities = capabilitiesIface->GetCapabilities(QList() << smContactHandle); if (!contactCapabilities.isValid()) { qDebug() << "GetCapabilities() returned error:" << contactCapabilities.error().name() << contactCapabilities.error().message() << "\n"; } else { qDebug() << "capabilities of conact" << smContactHandle << ":"; for (int i = 0; i < contactCapabilities.value().count(); ++i) { qDebug() << "\n\thandle:" << contactCapabilities.value().at(i).contactHandle << "\n\tchannel type:" << contactCapabilities.value().at(i).channelType << "\n\tgeneric flags:" << contactCapabilities.value().at(i).genericFlags << "\n\ttype specific flags:" << contactCapabilities.value().at(i).typeSpecificFlags << "\n"; if ((contactCapabilities.value().at(i).contactHandle == smContactHandle) && (contactCapabilities.value().at(i).channelType == "org.freedesktop.Telepathy.Channel.Type.StreamedMedia")) { isContactCapableOfStreamedMedia = true; smContactCapabilies = contactCapabilities.value().at(i).typeSpecificFlags; } } } // confirm that the contact is capable of streamed media if (!isContactCapableOfStreamedMedia) { qDebug() << smContactHandle <<"is not capable of streamed media.\n"; return; } #endif } } /** * the status of the connection has changed * * @param status * @param reason */ void MessageFilter::OnStatusChanged(uint status, uint reason) { qDebug() << "connection state has changed to" << status << "- reason" << reason; if (CONNECTION_STATUS_CONNECTING == status) { qDebug() << "connection is in progress...\n"; } else if (CONNECTION_STATUS_DISCONNECTED == status) { qDebug() << "connection has been disconnected.\n"; } else if (CONNECTION_STATUS_CONNECTED == status) { qDebug() << "connection has been connected:\n"; test_connection(); // test_connection_interface_aliasing(); // test_connection_interface_avatars(); test_connection_interface_capabilities(); // test_connection_interface_forwarding(); // test_connection_interface_presence(); // test_connection_interface_privacy(); // test_connection_interface_renaming(); // test_channel(); // test_channel_type_contactlist(); // test_channel_type_contactsearch(); test_channel_type_streamedmedia(); // test_channel_type_roomlist(); // test_channel_type_text(); // test_channel_type_tubes(); } else { qDebug() << "wrong connection status" << status << "should not have occured.\n"; } } /** * alias of some contacts has been changed * * @param newAliases */ void MessageFilter::onAliasesChanged(const org::freedesktop::Telepathy:: AliasInfoList& newAliases) { qDebug() << "alias of some contacts has been changed:"; foreach (org::freedesktop::Telepathy::AliasInfo alias, newAliases) { qDebug() << "\thandle:" << alias.contactHandle; QDBusReply handleName = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << alias.contactHandle); if (!handleName.isValid()) { qDebug() << "InspectHandles() returned error:" << handleName.error().name() << handleName.error().message() << "\n"; } else { qDebug() << "\tname:" << handleName.value().at(0); } qDebug() << "\tnew alias:" << alias.newAlias << "\n"; } } /** * avatar of contact has been updated * * @param contact in contact handle * @param new_avatar_token in new avatar token */ void MessageFilter::onAvatarUpdated(uint contact, const QString &new_avatar_token) { qDebug() << "avatar for contact has been updated:\n" << "\thandle:" << contact; QDBusReply handleName = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << contact); if (!handleName.isValid()) { qDebug() << "InspectHandles() returned error:" << handleName.error().name() << handleName.error().message() << "\n"; } else { qDebug() << "\tname:" << handleName.value().at(0); } qDebug() << "\ttoken:" << new_avatar_token << "\n"; } void MessageFilter::test_connection() { // get the existing interfaces on this connection QDBusReply interfaces = conn->GetInterfaces(); if (!interfaces.isValid()) { qDebug() << "GetInterfaces() returned error:" << interfaces.error().name() << interfaces.error().message() << "\n"; } else { qDebug() << "Supported interfaces on the connection:"; foreach (QString iface, interfaces.value()) { qDebug() << "\t" << iface; } } // get the used protocol of this connection QDBusReply protocol = conn->GetProtocol(); if (!protocol.isValid()) { qDebug() << "GetProtocol() returned error:" << protocol.error().name() << protocol.error().message() << "\n"; } else { qDebug() << "protocol used in the connection:" << protocol.value() << "\n"; } // get the handle of the connection itself QDBusReply selfHandle = conn->GetSelfHandle(); if (!selfHandle.isValid()) { qDebug() << "GetSelfHandle() returned error:" << selfHandle.error().name() << selfHandle.error().message() << "\n"; } else { qDebug() << "handle of user of the connection:" << selfHandle.value() << "\n"; } // get current connection status QDBusReply status = conn->GetStatus(); if (!status.isValid()) { qDebug() << "GetStatus() returned error:" << status.error().name() << status.error().message() << "\n"; } else { qDebug() << "current status of the connection:" << status.value() << "\n"; } // hold the connection handle QDBusReply ret = conn->HoldHandles(HANDLE_TYPE_CONTACT, QList() << selfHandle.value()); if (!ret.isValid()) { qDebug() << "HoldHandles() returned error:" << ret.error().name() << ret.error().message() << "\n"; } else { qDebug() << "handle of the connection" << selfHandle.value() << "is held\n"; } // get the handle name of the connection QDBusReply selfHandleName = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << selfHandle.value()); if (!selfHandleName.isValid()) { qDebug() << "InspectHandles() returned error:" << selfHandleName.error().name() << selfHandleName.error().message() << "\n"; } else { qDebug() << "handle of the connection" << selfHandle.value() << "is" << selfHandleName.value().at(0) << "\n"; } // list all the existing channels on this connection QDBusReply channels = conn->ListChannels(); if (!channels.isValid()) { qDebug() << "ListChannels() returned error:" << channels.error().name() << channels.error().message() << "\n"; } else { qDebug() << "existing channels on the connection:"; for (int i = 0; i < channels.value().size(); ++i) { org::freedesktop::Telepathy::ChannelInfo channel = channels.value().at(i); qDebug() << "\tpath:" << channel.objectPath.path() << "\n\tinterface:" << channel.interfaceName << "\n\thandle type:" << channel.handleType << "\n\thandle:" << channel.handle; if (channel.handle) { QDBusReply handleName = conn->InspectHandles(channel.handleType, QList() << channel.handle); if (!handleName.isValid()) { qDebug() << "InspectHandles() returned error:" << handleName.error().name() << handleName.error().message() << "\n"; } else { qDebug() << "\thandle name:" << handleName.value(); } } qDebug() << "\n"; } } // get some contact lists on this connection QStringList contactListNameList; contactListNameList << "subscribe" << "publish"; QDBusReply > contactListHandles = conn->RequestHandles(HANDLE_TYPE_LIST, contactListNameList); if (!contactListHandles.isValid()) { qDebug() << "RequestHandles() returned error:" << contactListHandles.error().name() << contactListHandles.error().message() << "\n"; } else { qDebug() << "contact list of" << contactListNameList << ":"; QDBusReply contactListHandleNames = conn->InspectHandles(HANDLE_TYPE_LIST, contactListHandles.value()); if (!contactListHandleNames.isValid()) { qDebug() << "InspectHandles() returned error:" << contactListHandleNames.error().name() << contactListHandleNames.error().message() << "\n"; } for (int i = 0; i < contactListHandles.value().count(); ++i) { quint32 handle = contactListHandles.value().at(i); qDebug() << "\thandle:" << contactListHandles.value().at(i); if (contactListHandleNames.isValid()) { qDebug() << "\tname:" << contactListHandleNames.value().at(i); } QDBusReply contactListChannelPath = conn->RequestChannel("org.freedesktop.Telepathy.Channel.Type." "ContactList", HANDLE_TYPE_LIST, handle, true); if (!contactListChannelPath.isValid()) { qDebug() << "RequestChannel() returned error:" << contactListChannelPath.error().name() << contactListChannelPath.error().message() << "\n"; } else { qDebug() << "\tobject path:" << contactListChannelPath.value().path() << "\n"; } } // release the handles not in use for the server to release them // in will QDBusReply releaseHandlesReply = conn->ReleaseHandles(HANDLE_TYPE_LIST, contactListHandles.value()); if (!releaseHandlesReply.isValid()) { qDebug() << "ReleaseHandles() returned error:" << releaseHandlesReply.error().name() << releaseHandlesReply.error().message() << "\n"; } else { qDebug() << "contact list handles" << contactListHandles.value() << "are all released.\n"; } } } void MessageFilter::test_connection_interface_aliasing() { // get the flags of the aliasing interface, if // Connection_Alias_Flag_User_Set is set, user can set alias of contact QDBusReply aliasFlags = aliasingIface->GetAliasFlags(); if (!aliasFlags.isValid()) { qDebug() << "GetAliasFlags() returned error:" << aliasFlags.error().name() << aliasFlags.error().message() << "\n"; } else { qDebug() << "flags of the aliasing interface of the connection:" << aliasFlags.value() << "\n"; } // get the handles of some contacts of this connection QDBusReply > contactHandles = conn->RequestHandles(HANDLE_TYPE_CONTACT, QStringList() << "izico@jabber.org" << "izicochang@gmail.com" << "izicoc@gmail.com" << "izico@msn.com"); if (!contactHandles.isValid()) { qDebug() << "RequestHandles() returned error:" << contactHandles.error().name() << contactHandles.error().message() << "\n"; } else { // get the aliases of the contacts QDBusReply contactAliases = aliasingIface->RequestAliases(contactHandles.value()); if (!contactAliases.isValid()) { qDebug() << "RequestAliases() returned error:" << contactAliases.error().name() << contactAliases.error().message() << "\n"; } else { qDebug() << "aliases for handles" << contactHandles.value(); QDBusReply handleNames = conn->InspectHandles(HANDLE_TYPE_CONTACT, contactHandles.value()); if (!handleNames.isValid()) { qDebug() << "InspectHandles() returned error:" << handleNames.error().name() << handleNames.error().message(); } else { qDebug() << "corresponding to users" << handleNames.value(); } qDebug() << "are" << contactAliases.value() << "\n"; } // set the aliases of contacts if the server support setting // contact aliases by user org::freedesktop::Telepathy::Aliases aliasMap; QString alias1 = "Izico Chang"; QString alias2 = "Izico Chang"; aliasMap[contactHandles.value().at(0)] = alias1; aliasMap[contactHandles.value().at(1)] = alias2; QDBusReply setAliasesReply = aliasingIface->SetAliases(aliasMap); if (!setAliasesReply.isValid()) { qDebug() << "SetAliases() returned error:" << setAliasesReply.error().name() << setAliasesReply.error().message() << "\n"; } else { qDebug() << "set alias of handle" << contactHandles.value().at(0) << "to" << alias1; qDebug() << "set alias of handle" << contactHandles.value().at(1) << "to" << alias2 << "\n"; } // release all the contact handles for server to release in will QDBusReply releaseHandlesReply = conn->ReleaseHandles(HANDLE_TYPE_CONTACT, contactHandles.value()); if (!releaseHandlesReply.isValid()) { qDebug() << "ReleaseHandles() returned error:" << releaseHandlesReply.error().name() << releaseHandlesReply.error().message() << "\n"; } else { qDebug() << "all contact handles" << contactHandles.value() << "are released.\n"; } } } void MessageFilter::test_connection_interface_avatars() { // get the required formats of the avatars on this connection struct { QStringList formats; ushort min_width; ushort min_height; ushort max_width; ushort max_height; uint max_size; } avatarRequirments; QDBusReply avatarRequirementsReply = avatarsIface->GetAvatarRequirements(avatarRequirments.min_width, avatarRequirments.min_height, avatarRequirments.max_width, avatarRequirments.max_height, avatarRequirments.max_size); if (!avatarRequirementsReply.isValid()) { qDebug() << "GetAvatarRequirements() returned error:" << avatarRequirementsReply.error().name() << avatarRequirementsReply.error().message() << "\n"; } else { avatarRequirments.formats = avatarRequirementsReply.value(); qDebug() << "Supported avatar formats are" << avatarRequirments.formats; qDebug() << "Required avatar geometry are(pixels):" << "\n\tmin width:" << avatarRequirments.min_width << "\n\tmin height:" << avatarRequirments.min_height << "\n\tmax width:" << avatarRequirments.max_width << "\n\tmax height:" << avatarRequirments.max_height << "\n\tmax size:" << avatarRequirments.max_size << "bytes\n" << "\n"; } // get the handle for some contacts QDBusReply > contactHandles = conn->RequestHandles(HANDLE_TYPE_CONTACT, QStringList() << "izicochang@gmail.com" << "izico@jabber.org"); if (!contactHandles.isValid()) { qDebug() << "RequestHandles() returned error:" << contactHandles.error().name() << contactHandles.error().message() << "\n"; } else { // get the avatar tokens to check for local cache QDBusReply contactAvatarTokens = avatarsIface->GetAvatarTokens(contactHandles); if (!contactAvatarTokens.isValid()) { qDebug() << "GetAvatarTokens() returned error:" << contactAvatarTokens.error().name() << contactAvatarTokens.error().message() << "\n"; } else { qDebug() << "avatar tokens for contact handles" << contactHandles.value() << "are" << contactAvatarTokens.value() << "\n"; } // get the avatars from server foreach (uint contactHandle, contactHandles.value()) { QString contactAvatarFormat; QDBusReply contactAvatarData = avatarsIface->RequestAvatar(contactHandle, contactAvatarFormat); if (!contactAvatarData.isValid()) { qDebug() << "RequestAvatar() returned error:" << contactAvatarData.error().name() << contactAvatarData.error().message() << "\n"; } else { qDebug() << "avatar for contact handle" << contactHandle << "of MIME type" << contactAvatarFormat << "and size" << contactAvatarData.value().size(); QString fileName = "avatar" + QString::number(contactHandle); QFile file(fileName); file.open(QIODevice::WriteOnly); file.write(contactAvatarData.value()); if (QFile::NoError != file.error()) { qDebug() << "can't be writen to file" << fileName << "\n"; } else { qDebug() << "is written to file" << fileName << "\n"; } } } QDBusReply reply = conn->ReleaseHandles(HANDLE_TYPE_CONTACT, contactHandles.value()); if (!reply.isValid()) { qDebug() << "ReleaseHandles() returned error:" << reply.error().name() << reply.error().message() << "\n"; } else { qDebug() << "contact handles" << contactHandles.value() << "is released.\n"; } } // clear avatar of this connection QDBusReply reply = avatarsIface->call(QDBus::Block, "ClearAvatar"); if (!reply.isValid()) { qDebug() << "call(ClearAvatar) returned error:" << reply.error().name() << reply.error().message() << "\n"; } else { qDebug() << "connection avatar is cleared.\n"; } // set avatar of this connection QString fileName("/home/src/qtopia-opensource-4.2.2/pics/qtopia.png"); QFile file(fileName); file.open(QIODevice::ReadOnly); QByteArray myAvatarData = file.readAll(); if (QFile::NoError != file.error()) { qDebug() << "can't read avatar file" << fileName << "\n"; } else { QString myAvatarType = "image/png"; QDBusReply connAvatarToken = avatarsIface->SetAvatar(myAvatarData, myAvatarType); if (!connAvatarToken.isValid()) { qDebug() << "SetAvatar() returned error:" << connAvatarToken.error().name() << connAvatarToken.error().message() << "\n"; } else { qDebug() << "new avatar for the connection" << connAvatarToken.value() << "is updated from file" << fileName << "\n"; } } } void MessageFilter::test_connection_interface_capabilities() { // advertise streamed media capability org::freedesktop::Telepathy::LocalCapabilityInfo addCapability; addCapability.channelType = "org.freedesktop.Telepathy.Channel.Type.StreamedMedia"; addCapability.typeSpecificFlags = (CHANNEL_MEDIA_CAPABILITY_AUDIO | CHANNEL_MEDIA_CAPABILITY_VIDEO | CHANNEL_MEDIA_CAPABILITY_NAT_TRAVERSAL_GTALK_P2P | CHANNEL_MEDIA_CAPABILITY_NAT_TRAVERSAL_STUN); org::freedesktop::Telepathy::LocalCapabilityInfoList addCapabilities; addCapabilities << addCapability; // remove capabilities QStringList removeCapabilities; // advertise my capabilities QDBusReply connectionCapabilities = capabilitiesIface->AdvertiseCapabilities(addCapabilities, removeCapabilities); if (!connectionCapabilities.isValid()) { qDebug() << "AdvertiseCapabilities() returned error:" << connectionCapabilities.error().name() << connectionCapabilities.error().message() << "\n"; } else { qDebug() << "capabilities of the connection are:"; for (int i = 0; i < connectionCapabilities.value().count(); ++i) { qDebug() << "\tchannel type:" << connectionCapabilities.value().at(i).channelType << "\n\ttype specific capability flags:" << connectionCapabilities.value().at(i).typeSpecificFlags << "\n"; } } // get handles of some contacts and the connection itself QDBusReply > contactHandleList = conn->RequestHandles(HANDLE_TYPE_CONTACT, QStringList() << "izicochang@gmail.com" << "izico0@gmail.com"); if (!contactHandleList.isValid()) { qDebug() << "RequestHandles() returned error:" << contactHandleList.error().name() << contactHandleList.error().message() << "\n"; } else { // get the capabilities of the contacts QDBusReply contactCapabilitiesList = capabilitiesIface->GetCapabilities(QList() << 0 << contactHandleList.value()); if (!contactCapabilitiesList.isValid()) { qDebug() << "GetCapabilities() returned error:" << contactCapabilitiesList.error().name() << contactCapabilitiesList.error().message() << "\n"; } else { qDebug() << "capabilities of some contacts:\n"; for (int i =0; i < contactCapabilitiesList.value().count(); ++i) { qDebug() << "\thandle:" << contactCapabilitiesList.value().at(i).contactHandle; QDBusReply handleName = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << contactCapabilitiesList.value().at(i).contactHandle); if (!handleName.isValid()) { qDebug() << "InspectHandles() returned error:" << handleName.error().name() << handleName.error().message() << "\n"; } else { qDebug() << "\tname:" << handleName.value().at(0); } qDebug() << "\tchannel type:" << contactCapabilitiesList.value().at(i).channelType << "\n\tgeneric capability flags for the type:" << contactCapabilitiesList.value().at(i).genericFlags << "\n\ttype specific capability flags for the type:" << contactCapabilitiesList.value().at(i).typeSpecificFlags << "\n"; } } } } void MessageFilter::onCapabilitiesChanged(const org::freedesktop::Telepathy::CapabilitiesChangedInfoList& caps) { qDebug() << "capabilities of" << caps.count() << "contacts has been changed:"; for (int i = 0; i < caps.count(); ++i) { qDebug() << "\thandle:" << caps.at(i).contactHandle; QDBusReply contactName = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << caps.at(i).contactHandle); if (!contactName.isValid()) { qDebug() << "InspectHandles() returned error:" << contactName.error().name() << contactName.error().message() << "\n"; } else { qDebug() << "\tname:" << contactName.value().at(0); } qDebug() << "\tchannel type:" << caps.at(i).channelType << "\n\told generic capability flags:" << caps.at(i).oldGenericFlags << "\n\tnew generic capability flags:" << caps.at(i).newGenericFlags << "\n\told type specific capability flags:" << caps.at(i).oldTypeSpecificFlags << "\n\tnew type specific capability flags:" << caps.at(i).newTypeSpecificFlags << "\n"; } } /** * FIXME org.freedesktop.DBus.Error.UnknownMethod */ void MessageFilter::test_connection_interface_forwarding() { // disable forwarding QDBusReply reply = forwardingIface->SetForwardingHandle(0); if (!reply.isValid()) { qDebug() << "SetForwardingHandle() returned error:" << reply.error().name() << reply.error().message() << "\n"; } else { qDebug() << "forwarding is disabled on the connection.\n"; } QDBusReply forwardingHandle = forwardingIface->GetForwardingHandle(); if (!forwardingHandle.isValid()) { qDebug() << "GetForwardingHandle() returned error:" << forwardingHandle.error().name() << forwardingHandle.error().message() << "\n"; } else { qDebug() << "forwarding handle of the connection:" << forwardingHandle.value() << "\n"; } } void MessageFilter::onForwardingChanged(uint forward_to) { if (!forward_to) { qDebug() << "forwarding has been disabled on the connection.\n"; } else { qDebug() << "forwarding contact has been changed to handle" << forward_to << "on the connection.\n"; } } void MessageFilter::test_connection_interface_presence() { // clear presence status of connection QDBusReply clearStatusReply = presenceIface->ClearStatus(); if (!clearStatusReply.isValid()) { qDebug() << "ClearStatus() returned error:" << clearStatusReply.error().name() << clearStatusReply.error().message() << "\n"; } else { qDebug() << "presence status of the connection is cleared.\n"; } // remove presence status of connection QDBusReply removeStatusReply = presenceIface->RemoveStatus("available"); if (!removeStatusReply.isValid()) { qDebug() << "RemoveStatus() returned error:" << removeStatusReply.error().name() << removeStatusReply.error().message() << "\n"; } else { qDebug() << "status \"available\" is removed from connection.\n"; } org::freedesktop::Telepathy::PresenceState setStatus; setStatus["xa"] = QVariantMap(); QDBusReply setStatusReply = presenceIface->SetStatus(setStatus); if (!setStatusReply.isValid()) { qDebug() << "SetStatus() returned error:" << setStatusReply.error().name() << setStatusReply.error().message() << "\n"; } else { qDebug() << "presence state of connection is set to \"xa\"\n"; } // FIXME "Only one status is possible at a time with this protocol" // set presence status of connection QString connPresenceStatus = "xa"; QVariantMap connPresenceParams; QDBusReply addStatusReply = presenceIface->AddStatus(connPresenceStatus, connPresenceParams); if (!addStatusReply.isValid()) { qDebug() << "AddStatus() returned error:" << addStatusReply.error().name() << addStatusReply.error().message() << "\n"; } else { qDebug() << "presence status is set to" << connPresenceStatus << "\n"; } // get handles of some contacts QDBusReply > contactHandles = conn->RequestHandles(HANDLE_TYPE_CONTACT, QStringList() << "izicochang@gmail.com" << "izico@jabber.org"); if (!contactHandles.isValid()) { qDebug() << "RequestHandles() returned error:" << contactHandles.error().name() << contactHandles.error().message() << "\n"; } else { // get presence of some contacts QList argumentList; argumentList << qVariantFromValue(contactHandles.value()); QDBusReply contactsPresence = presenceIface->callWithArgumentList(QDBus::Block, "GetPresence", argumentList); if (!contactsPresence.isValid()) { qDebug() << "call(GetPresence) returned error:" << contactsPresence.error().name() << contactsPresence.error().message() << "\n"; } else { qDebug() << "presence of some contacts are:"; foreach (uint handle, contactsPresence.value().keys()) { qDebug() << "\thandle:" << handle; QDBusReply handleName = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << handle); if (!handleName.isValid()) { qDebug() << "InspectHandles() returned error:" << handleName.error().name() << handleName.error().message() << "\n"; } else { qDebug() << "\tname:" << handleName.value().at(0); } quint32 timestamp = contactsPresence.value()[handle].time; qDebug() << "\ttimestamp:" << timestamp; PresenceState state = contactsPresence.value()[handle].state; foreach (QString status, state.keys()) { qDebug() << "\tstatus:" << status; QVariantMap params = state[status]; qDebug() << "\tparameters:" << params << "\n"; } } } QDBusReply reply = presenceIface->RequestPresence(contactHandles); if (!reply.isValid()) { qDebug() << "RequestPresence() returned error:" << reply.error().name() << reply.error().message() << "\n"; } else { qDebug() << "presence of some contacts is requested.\n"; } QDBusReply releaseHandlesReply = conn->ReleaseHandles(HANDLE_TYPE_CONTACT, contactHandles); if (!releaseHandlesReply.isValid()) { qDebug() << "ReleaseHandles() returned error:" << releaseHandlesReply.error().name() << releaseHandlesReply.error().message() << "\n"; } else { qDebug() << "contact handles" << contactHandles.value() << "are released.\n"; } } // FIXME unexpected reply signature org.freedesktop.DBus.Error.InvalidSignature // get valid presense status of the connection from server QDBusReply statuses = presenceIface->GetStatuses(); if (!statuses.isValid()) { qDebug() << "GetStatuses() returned error:" << statuses.error().name() << statuses.error().message() << "\n"; } else { qDebug() << "valid presence statuses of the connection are:"; foreach (QString name, statuses.value().keys()) { qDebug() << "\t" << name << ":"; org::freedesktop::Telepathy::PresenceStateDefinition definition = statuses.value()[name]; qDebug() << "\type:" << definition.type << "\n\tmaySetOnMyself:" << definition.maySetOnMyself << "\n\tisExclusive:" << definition.isExclusive << "\n\targument map {name, type} :" << definition.arguments << "\n"; } } QDBusReply setLastActivityTimeReply = presenceIface->SetLastActivityTime(100); if (!setLastActivityTimeReply.isValid()) { qDebug() << "SetLastActivityTime() returned error:" << setLastActivityTimeReply.error().name() << setLastActivityTimeReply.error().message() << "\n"; } else { qDebug() << "last activity time has been set to 100.\n"; } } void MessageFilter::onPresenceUpdate(const org::freedesktop::Telepathy::PresenceStateInTimeMap& presence) { qDebug() << "presence of some contacts has been updated:"; foreach (uint handle, presence.keys()) { qDebug() << "\thandle:" << handle; QDBusReply handleName = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << handle); if (!handleName.isValid()) { qDebug() << "InspectHandles() returned error:" << handleName.error().name() << handleName.error().message() << "\n"; } else { qDebug() << "\tname:" << handleName.value().at(0); } quint32 timestamp = presence[handle].time; qDebug() << "\ttimestamp:" << timestamp; PresenceState state = presence[handle].state; foreach (QString status, state.keys()) { qDebug() << "\tstatus:" << status; QVariantMap params = state[status]; qDebug() << "\tparameters:" << params << "\n"; } } } /** * FIXME org.freedesktop.DBus.Error.UnknownMethod */ void MessageFilter::test_connection_interface_privacy() { QDBusReply supportedPrivacyModes = privacyIface->GetPrivacyModes(); if (!supportedPrivacyModes.isValid()) { qDebug() << "GetPrivacyModes() returned error:" << supportedPrivacyModes.error().name() << supportedPrivacyModes.error().message() << "\n"; } else { qDebug() << "supported privacy modes of the connection:" << supportedPrivacyModes.value() << "\n"; } QDBusReply currentPrivacyMode = privacyIface->GetPrivacyMode(); if (!currentPrivacyMode.isValid()) { qDebug() << "GetPrivacyMode() returned error:" << currentPrivacyMode.error().name() << currentPrivacyMode.error().message() << "\n"; } else { qDebug() << "current privacy mode of the connecition is" << currentPrivacyMode.value() << "\n"; } QDBusReply setPrivacyModeReply = privacyIface->SetPrivacyMode("allow-all"); if (!setPrivacyModeReply.isValid()) { qDebug() << "SetPrivacyMode() returned error:" << setPrivacyModeReply.error().name() << setPrivacyModeReply.error().message() << "\n"; } else { qDebug() << "privacy mode of the connection is set to" << "\"allow-all\"\n"; } } void MessageFilter::onPrivacyModeChanged(const QString& mode) { qDebug() << "privacy mode of the connection has been changed to" << mode << "\n"; } /** * FIXME org.freedesktop.DBus.Error.UnknownMethod */ void MessageFilter::test_connection_interface_renaming() { QString newName("izicochang@gmail.com"); QDBusReply requestRenameReply = renamingIface->RequestRename(newName); if (!requestRenameReply.isValid()) { qDebug() << "RequestRename() returned error:" << requestRenameReply.error().name() << requestRenameReply.error().message() << "\n"; } else { qDebug() << "user identifier of the connection is renamed to" << newName << "\n"; } } void MessageFilter::onRenamed(uint old_handle, uint new_handle) { qDebug() << "handle" << old_handle << "has been renamed to" << "new handle" << new_handle << "\n"; } void MessageFilter::test_channel() { // create an anonymose channel QString channelType = "org.freedesktop.Telepathy.Channel.Type.StreamedMedia"; QDBusReply channelPath = conn->RequestChannel(channelType, 0, 0, true); if (!channelPath.isValid()) { qDebug() << "RequestChannel() returned error:" << channelPath.error().name() << channelPath.error().message() << "\n"; } else { qDebug() << "anonymouse channel is created:" << "\n\tchannel type:" << channelType << "\n\tpath:" << channelPath.value().path() << "\n"; // get the Channel interface anonymousChannel = new Channel(conn->service(), channelPath.value().path(), bus, this); connect(anonymousChannel, SIGNAL(Closed()), this, SLOT(onClose())); QDBusReply gotChannelType = anonymousChannel->GetChannelType(); if (!gotChannelType.isValid()) { qDebug() << "GetChannelType() returned error:" << gotChannelType.error().name() << gotChannelType.error().message() << "\n"; } else { qDebug() << "confirmed channel type:" << gotChannelType.value() << "\n"; } uint handle; QDBusReply handleType = anonymousChannel->GetHandle(handle); if (!handleType.isValid()) { qDebug() << "GetHandle() returned error:" << handleType.error().name() << handleType.error().message() << "\n"; } else { qDebug() << "the channnel is for cummunication with:" << "\n\thandle type:" << handleType.value() << "\n\thandle:" << handle << "\n"; } QDBusReply interfaces = anonymousChannel->GetInterfaces(); if (!interfaces.isValid()) { qDebug() << "GetInterfaces() returned error:" << interfaces.error().name() << interfaces.error().message() << "\n"; } else { qDebug() << "supported interfaces on the channel:"; foreach (QString interface, interfaces.value()) { qDebug() << "\t" << interface; } qDebug() << "\n"; } // close the channel QDBusReply closeReply = anonymousChannel->Close(); if (!closeReply.isValid()) { qDebug() << "Close() returned error:" << closeReply.error().name() << closeReply.error().message() << "\n"; } else { qDebug() << "channel" << channelPath.value().path() << "is closed.\n"; } } } void MessageFilter::onClose() { qDebug() << "one channel has been closed.\n"; } /** * FIXME: * * Transfer - org.freedesktop.DBus.Error.UnknownMethod */ void MessageFilter::test_channel_type_contactlist() { // get some contact list handles QStringList contactListNameList; // "allow" and "hide" is not valid on izico.zhang@gmail.com contactListNameList << "subscribe" << "publish" << "deny" << "known"; QDBusReply > contactListHandleList = conn->RequestHandles(HANDLE_TYPE_LIST, contactListNameList); if (!contactListHandleList.isValid()) { qDebug() << "RequestHandles() returned error:" << contactListHandleList.error().name() << contactListHandleList.error().message() << "\n"; return; } Q_ASSERT(contactListHandleList.value().count() == 4); for (int i = 0; i < contactListHandleList.value().count(); ++i) { uint contactListHandle = contactListHandleList.value().at(i); QString contactListName = contactListNameList.at(i); QDBusReply contactListPath = conn->RequestChannel("org.freedesktop.Telepathy.Channel.Type.ContactList", HANDLE_TYPE_LIST, contactListHandle, true); if (!contactListPath.isValid()) { qDebug() << "RequestChannel() returned error:" << contactListPath.error().name() << contactListPath.error().message() << "\n"; } else { qDebug() << "contact list channel:" << "\n\thandle:" << contactListHandle << "\n\tname:" << contactListNameList.at(i) << "\n\tobject path:" << contactListPath.value().path(); } contactListChannel[i] = new Channel(conn->service(), contactListPath.value().path(), bus, this); connect(contactListChannel[i], SIGNAL(Closed()), this, SLOT(onClose())); contactListChannelGroupIface[i] = new ChannelGroupInterface(conn->service(), contactListPath.value().path(), bus, this); connect(contactListChannelGroupIface[i], SIGNAL(GroupFlagsChanged(uint, uint)), this, SLOT(onGroupFlagsChanged(uint, uint))); connect(contactListChannelGroupIface[i], SIGNAL(MembersChanged(QString, QList, QList, QList, QList, uint, uint)), this, SLOT(onMembersChanged(QString, QList, QList, QList, QList, uint, uint))); // FIXME: org.freedesktop.DBus.Error.UnknownMethod ChannelTransferInterface transferIface(conn->service(), contactListPath.value().path(), bus, this); QDBusReply transferReply = transferIface.Transfer(1, 2); if (!transferReply.isValid()) { qDebug() << "Transfer() returned error:" << transferReply.error().name() << transferReply.error().message() << "\n"; } else { qDebug() << "channel member 1 will connect with 2 indead.\n"; } // get flags of this channel QDBusReply channelFlags = contactListChannelGroupIface[i]->GetGroupFlags(); if (!channelFlags.isValid()) { qDebug() << "GetGroupFlags() returned error:" << channelFlags.error().name() << channelFlags.error().message() << "\n"; } else { qDebug() << "\tflags: 0x" << hex << channelFlags.value(); } // add some members to "subscribe" contact list if ((contactListName == "subscribe") && channelFlags.isValid() && (channelFlags & CHANNEL_GROUP_FLAG_CAN_ADD)) { QStringList addMemberNameList; addMemberNameList << "izico0@gmail.com" << "ext+130@truphone.com"; QDBusReply > addMemberList = conn->RequestHandles(HANDLE_TYPE_CONTACT, addMemberNameList); if (!addMemberList.isValid()) { qDebug() << "RequestHandles() returned error:" << addMemberList.error().name() << addMemberList.error().message() << "\n"; } else { QDBusReply addMembersReply = contactListChannelGroupIface[i]->AddMembers(addMemberList, "add members"); if (!addMembersReply.isValid()) { qDebug() << "AddMembers() returned error:" << addMembersReply.error().name() << addMembersReply.error().message() << "\n"; } else { qDebug() << "\tadded members:" << addMemberNameList; } } } // remove some contacts in "publish" lis if ((contactListName == "publish") && channelFlags.isValid() && (channelFlags & CHANNEL_GROUP_FLAG_CAN_REMOVE)) { QStringList removeMemberNameList; removeMemberNameList << "izicochang@gmail.com"; QDBusReply > removeMemberHandleList = conn->RequestHandles(HANDLE_TYPE_CONTACT, removeMemberNameList); if (!removeMemberHandleList.isValid()) { qDebug() << "RequestHandles() returned error:" << removeMemberHandleList.error().name() << removeMemberHandleList.error().message() << "\n"; } else { QDBusReply removeMembersReply = contactListChannelGroupIface[i]->RemoveMembers(removeMemberHandleList, "remove members"); if (!removeMembersReply.isValid()) { qDebug() << "RemoveMembers() returned error:" << removeMembersReply.error().name() << removeMembersReply.error().message() << "\n"; } else { qDebug() << "\tremoved members:" << removeMemberHandleList.value(); } } } QList localPendingMemberHandleList; QList remotePendingMemberHandleList; QDBusReply > currentMemberHandleList = contactListChannelGroupIface[i]->GetAllMembers(localPendingMemberHandleList, remotePendingMemberHandleList); if (!currentMemberHandleList.isValid()) { qDebug() << "GetAllMembers() returned error:" << currentMemberHandleList.error().name() << currentMemberHandleList.error().message() << "\n"; } else { qDebug() << "\tcurrent members:\n" << "\t\thandles:" << currentMemberHandleList.value(); QDBusReply currentMemberNameList = conn->InspectHandles(HANDLE_TYPE_CONTACT, currentMemberHandleList.value()); if (!currentMemberNameList.isValid()) { qDebug() << "InspectHandles() returned error:" << currentMemberNameList.error().name() << currentMemberNameList.error().message() << "\n"; } else { qDebug() << "\t\tnames:" << currentMemberNameList.value(); } if (channelFlags.isValid() && (channelFlags.value() & CHANNEL_GROUP_FLAG_CHANNEL_SPECIFIC_HANDLES)) { QDBusReply > currentMemberHandleOwnerList = contactListChannelGroupIface[i]->GetHandleOwners(currentMemberHandleList.value()); if (!currentMemberHandleOwnerList.isValid()) { qDebug() << "GetHandleOwners() returned error:" << currentMemberHandleOwnerList.error().name() << currentMemberHandleOwnerList.error().message() << "\n"; } else { qDebug() << "owner of handles of current members:" << currentMemberHandleOwnerList.value(); } } qDebug() << "\tlocal pending members:\n" << "\t\thandles:" << localPendingMemberHandleList; QDBusReply localPendingMemberNameList = conn->InspectHandles(HANDLE_TYPE_CONTACT, localPendingMemberHandleList); if (!localPendingMemberNameList.isValid()) { qDebug() << "InspectHandles() returned error:" << localPendingMemberNameList.error().name() << localPendingMemberNameList.error().message() << "\n"; } else { qDebug() << "\t\tnames:" << localPendingMemberNameList.value(); } qDebug() << "\tremote pending members:\n" << "\t\thandles:" << remotePendingMemberHandleList; QDBusReply remotePendingMemberNameList = conn->InspectHandles(HANDLE_TYPE_CONTACT, remotePendingMemberHandleList); if (!remotePendingMemberNameList.isValid()) { qDebug() << "InspectHandles() returned error:" << remotePendingMemberNameList.error().name() << remotePendingMemberNameList.error().message() << "\n"; } else { qDebug() << "\t\tnames:" << remotePendingMemberNameList.value(); } } QDBusReply > currentMemberHandleList2 = contactListChannelGroupIface[i]->GetMembers(); if (!currentMemberHandleList2.isValid()) { qDebug() << "GetMembers() returned error:" << currentMemberHandleList2.error().name() << currentMemberHandleList2.error().message() << "\n"; } else { qDebug() << "\tconfirmed current member handles:" << currentMemberHandleList2.value(); } QDBusReply > localPendingMemberHandleList2 = contactListChannelGroupIface[i]->GetLocalPendingMembers(); if (!localPendingMemberHandleList2.isValid()) { qDebug() << "GetLocalPendingMembers() returned error:" << localPendingMemberHandleList2.error().name() << localPendingMemberHandleList2.error().message() << "\n"; } else { qDebug() << "\tconfirmed local pending member handles:" << localPendingMemberHandleList2.value(); } // XXX in telepathy spec,but not telepathy-qt API QDBusMessage replyMessage = contactListChannelGroupIface[i]->call(QDBus::Block, "GetLocalPendingMembersWithInfo"); if (contactListChannelGroupIface[i]->lastError().isValid()) { qDebug() << "call(GetLocalPendingMembersWithInfo)" "returned error:" << contactListChannelGroupIface[i]->lastError().name() << contactListChannelGroupIface[i]->lastError().message() << "\n"; } else { // should write marshall/demarshall routine to get reply } QDBusReply > remotePendingMemberHandleList2 = contactListChannelGroupIface[i]->GetRemotePendingMembers(); if (!remotePendingMemberHandleList2.isValid()) { qDebug() << "GetRemotePendingMembers() returned error:" << remotePendingMemberHandleList2.error().name() << remotePendingMemberHandleList2.error().message() << "\n"; } else { qDebug() << "\tconfirmed remote pending member handles:" << remotePendingMemberHandleList2.value() << "\n"; } QDBusReply selfHandle = contactListChannelGroupIface[i]->GetSelfHandle(); if (!selfHandle.isValid()) { qDebug() << "GetSelfHandle() returned error:" << selfHandle.error().name() << selfHandle.error().message() << "\n"; } else { if (selfHandle.value()) { qDebug() << "\thandle of the channel user:" << selfHandle.value(); QDBusReply selfHandleNameList = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << selfHandle.value()); if (!selfHandleNameList.isValid()) { qDebug() << "InspectHandles() returned error:" << selfHandleNameList.error().name() << selfHandleNameList.error().message() << "\n"; } else { qDebug() << "\tname of the channel user:" << selfHandleNameList.value().at(0); } } } } QDBusReply releaseHandlesReply = conn->ReleaseHandles(HANDLE_TYPE_LIST, contactListHandleList); if (!releaseHandlesReply.isValid()) { qDebug() << "ReleaseHandles() returned error:" << releaseHandlesReply.error().name() << releaseHandlesReply.error().message() << "\n"; } else { qDebug() << "all handles" << contactListHandleList.value() << "are released.\n"; } } void MessageFilter::onGroupFlagsChanged(uint added, uint removed) { qDebug() << "group flags of one channel has been changed:" << "\n\tadded flags:" << hex << added << "\n\tremoved flags:" << hex << removed << "\n"; } void MessageFilter::onMembersChanged(const QString &message, const QList &added, const QList &removed, const QList &local_pending, const QList &remote_pending, uint actor, uint reason) { qDebug() << "members of one channel has changed:\n" << "\n\tmessage:" << message << "\n\tadded members:" << added << "\n\tremoved members:" << removed << "\n\tlocal pending members:" << local_pending << "\n\tremote pending members:" << remote_pending << "\n\tuser making the change:" << actor << "\n\treason for the change:" << reason << "\n"; } /** * FIXME * unsupported channel type * "org.freedesktop.Telepathy.Channel.Type.ContactSearch" */ void MessageFilter::test_channel_type_contactsearch() { QStringList contactListNames; contactListNames << "subscribe" << "publish" << "deny"; QDBusReply > contactListHandles = conn->RequestHandles(HANDLE_TYPE_LIST, contactListNames); if (!contactListHandles.isValid()) { qDebug() << "RequestHandles() returned error:" << contactListHandles.error().name() << contactListHandles.error().message() << "\n"; return; } qDebug() << "contact search channel:"; foreach (uint contactListHandle, contactListHandles.value()) { QDBusReply searchPath = conn->RequestChannel("org.freedesktop.Telepathy.Channel.Type.ContactSearch", HANDLE_TYPE_LIST, contactListHandle, true); if (!searchPath.isValid()) { qDebug() << "RequestChannel() returned error:" << searchPath.error().name() << searchPath.error().message() << "\n"; } else { qDebug() << "\thandle:" << contactListHandle << "\n\tsearch path:" << searchPath.value().path(); ChannelContactSearch searchChannel(conn->service(), searchPath.value().path(), bus); ContactSearchTypeInfoMap searchKeys; QDBusReply instructions = searchChannel.GetSearchKeys(searchKeys); if (!instructions.isValid()) { qDebug() << "GetSearchKeys() returned error:" << instructions.error().name() << instructions.error().message() << "\n"; } } } } /** * FIXME */ void MessageFilter::test_channel_type_roomlist() { /* FIXME "org.freedesktop.Telepathy.Error.NotAvailable" "requested room handle conference.jabber.org does not specify a server, but we have not discovered any local conference servers and no fallback was provided" with null server lists will return back 0 handles the call has succeeded once,but don't know why never succeed again later */ QStringList conferenceServerList; conferenceServerList << "ubuntu"; QDBusReply > roomListHandleList = conn->RequestHandles(HANDLE_TYPE_ROOM, conferenceServerList); if (!roomListHandleList.isValid()) { qDebug() << "RequestHandles() returned error:" << roomListHandleList.error().name() << roomListHandleList.error().message() << "\n"; return; } qDebug() << "There are" << roomListHandleList.value().count() << "rooms on the conference server"; if (roomListHandleList.value().isEmpty()) { return; } uint roomListHandle = roomListHandleList.value().at(0); QDBusReply roomListPath = conn->RequestChannel("org.freedesktop.Telepathy.Channel.Type.RoomList", HANDLE_TYPE_ROOM, roomListHandle, true); if (!roomListPath.isValid()) { qDebug() << "RequestChannel() returned error:" << roomListPath.error().name() << roomListPath.error().message() << "\n"; return; } qDebug() << "room list is created on:" <<"\n\tobject path:" << roomListPath.value().path(); } /** * XXX the properties is not exported in telepathy-qt API * XXX the chat state interface signals are not received */ void MessageFilter::test_channel_type_text() { QStringList contactNameList; contactNameList << "izicochang@gmail.com"; // contactNameList << "izico@jabber.org"; // contactNameList << "izico.zhang@gmail.com"; QDBusReply > contactHandleList = conn->RequestHandles(HANDLE_TYPE_CONTACT, contactNameList); if (!contactHandleList.isValid()) { qDebug() << "RequestHandles() returned error:" << contactHandleList.error().name() << contactHandleList.error().message() << "\n"; return; } if (contactHandleList.value().isEmpty()) { return; } uint contactHandle = contactHandleList.value().at(0); QDBusReply channelPath = conn->RequestChannel("org.freedesktop.Telepathy.Channel.Type.Text", HANDLE_TYPE_CONTACT, contactHandle, true); if (!channelPath.isValid()) { qDebug() << "RequestChannel() returned error:" << channelPath.error().name() << channelPath.error().message() << "\n"; return; } qDebug() << "text channel is created on:" << "\n\tobject path:" << channelPath.value().path() << "\n"; // init the channel textChannel = new Channel(conn->service(), channelPath.value().path(), bus, this); connect(textChannel, SIGNAL(Closed()), this, SLOT(onClose())); // init the channel type text textChannelType = new ChannelText(conn->service(), channelPath.value().path(), bus, this); connect(textChannelType, SIGNAL(LostMessage()), this, SLOT(onLostMessage())); connect(textChannelType, SIGNAL(Received(uint, uint, uint, uint, uint, QString)), this, SLOT(onReceived(uint, uint, uint, uint, uint, QString))); connect(textChannelType, SIGNAL(SendError(uint, uint, uint, QString)), this, SLOT(onSendError(uint, uint, uint, QString))); connect(textChannelType, SIGNAL(Sent(uint, uint, QString)), this, SLOT(onSent(uint, uint, QString))); // init the channel interface chatstate textChannelChatStateIface = new ChannelChatStateInterface(conn->service(), channelPath.value().path(), bus, this); connect(textChannelChatStateIface, SIGNAL(ChatStateChanged(uint, uint)), this, SLOT(onChatStateChanged(uint, uint))); QDBusReply setChatStateReply = textChannelChatStateIface->SetChatState(CHANNEL_CHAT_STATE_ACTIVE); if (!setChatStateReply.isValid()) { qDebug() << "SetChatState() returned error:" << setChatStateReply.error().name() << setChatStateReply.error().message() << "\n"; } else { qDebug() << "chat state is set to \"active\"\n"; } QDBusReply messageTypeList = textChannelType->GetMessageTypes(); if (!messageTypeList.isValid()) { qDebug() << "GetMessageTypes() returned error:" << messageTypeList.error().name() << messageTypeList.error().message() << "\n"; } else { qDebug() << "supported text message types:" << messageTypeList.value() << "\n"; } QString sendString("hello,world."); QDBusReply sendReply = textChannelType->Send(CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, sendString); if (!sendReply.isValid()) { qDebug() << sendReply.error().name() << sendReply.error().message() << "\n"; } else { qDebug() << "message" << sendString << "is sent.\n"; } QDBusReply pendingMessageList = textChannelType->ListPendingMessages(false); if (!pendingMessageList.isValid()) { qDebug() << "ListPendingMessages() returned error:" << pendingMessageList.error().name() << pendingMessageList.error().message() << "\n"; } else { qDebug() << "there are" << pendingMessageList.value().count() << "pending messages:"; foreach (TextMessageInfo m, pendingMessageList.value()) { qDebug() << "\n\tid:" << m.id << "\n\ttimestamp:" << m.timestamp << "\n\ttype:" << m.type << "\n\tcontact handle:" << m.contactHandle << "\n\tflags:" << m.flags << "\n\tmessage:" << m.message << "\n"; } } setChatStateReply = textChannelChatStateIface->SetChatState(CHANNEL_CHAT_STATE_INACTIVE); if (!setChatStateReply.isValid()) { qDebug() << "SetChatState() returned error:" << setChatStateReply.error().name() << setChatStateReply.error().message() << "\n"; } else { qDebug() << "chat state is set to \"inactive\"\n"; } } void MessageFilter::onLostMessage() { qDebug() << "one incomming message has been lost by CM.\n"; } void MessageFilter::onReceived(uint id, uint timestamp, uint sender, uint type, uint flags, const QString& text) { qDebug() << "one message has been received:" << "\n\tid:" << id << "\n\ttimestamp:" << timestamp << "\n\tsender:" << sender << "\n\ttype:" << type << "\n\tflags:" << flags << "\n\ttext:" << text << "\n"; QDBusReply pendingMessageList = textChannelType->ListPendingMessages(false); if (!pendingMessageList.isValid()) { qDebug() << "ListPendingMessages() returned error:" << pendingMessageList.error().name() << pendingMessageList.error().message() << "\n"; } else { qDebug() << "there are" << pendingMessageList.value().count() << "pending messages before acknowledged:"; foreach (TextMessageInfo m, pendingMessageList.value()) { qDebug() << "\n\tid:" << m.id << "\n\ttimestamp:" << m.timestamp << "\n\ttype:" << m.type << "\n\tcontact handle:" << m.contactHandle << "\n\tflags:" << m.flags << "\n\tmessage:" << m.message << "\n"; } } QDBusReply reply = textChannelType->AcknowledgePendingMessages(QList() << id); if (!reply.isValid()) { qDebug() << "AcknowledgePendingMessages() returned error:" << reply.error().name() << reply.error().message() << "\n"; } else { qDebug() << "message of id" << id << "has been acknowledged.\n"; } pendingMessageList = textChannelType->ListPendingMessages(false); if (!pendingMessageList.isValid()) { qDebug() << "ListPendingMessages() returned error:" << pendingMessageList.error().name() << pendingMessageList.error().message() << "\n"; } else { qDebug() << "there are" << pendingMessageList.value().count() << "pending messages after acknowledged:"; foreach (TextMessageInfo m, pendingMessageList.value()) { qDebug() << "\n\tid:" << m.id << "\n\ttimestamp:" << m.timestamp << "\n\ttype:" << m.type << "\n\tcontact handle:" << m.contactHandle << "\n\tflags:" << m.flags << "\n\tmessage:" << m.message << "\n"; } } QDBusReply sendReply = textChannelType->Send(CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, text); if (!sendReply.isValid()) { qDebug() << "Send() returned error:" << sendReply.error().name() << sendReply.error().message() << "\n"; } else { qDebug() << "message" << text << "is echoed back to sender.\n"; } } void MessageFilter::onSendError(uint error, uint timestamp, uint type, const QString& text) { qDebug() << "one message failed to send:" << "\n\terror:" << error << "\n\ttimestamp:" << timestamp << "\n\ttype:" << type << "\n\ttext:" << text << "\n"; } void MessageFilter::onSent(uint timestamp,uint type, const QString& text) { qDebug() << "one message has been sent:" << "\n\ttimestamp:" << timestamp << "\n\ttype:" << type << "\n\ttext:" << text << "\n"; } /** * FIXME "org.freedesktop.Telepathy.Error.NotImplemented" * "unsupported channel type org.freedesktop.Telepathy.Channel.Type.Tubes" */ void MessageFilter::test_channel_type_tubes() { QStringList contactNameList; contactNameList << "izicochang@gmail.com"; QDBusReply > contactHandleList = conn->RequestHandles(HANDLE_TYPE_CONTACT, contactNameList); if (!contactHandleList.isValid()) { qDebug() << "RequestHandles() returned error:" << contactHandleList.error().name() << contactHandleList.error().message() << "\n"; return; } if (contactHandleList.value().isEmpty()) { return; } uint contactHandle = contactHandleList.value().at(0); QDBusReply channelPath = conn->RequestChannel("org.freedesktop.Telepathy.Channel.Type.Tubes", HANDLE_TYPE_CONTACT, contactHandle, true); if (!channelPath.isValid()) { qDebug() << "RequestChannel() returned error:" << channelPath.error().name() << channelPath.error().message() << "\n"; return; } qDebug() << "tube channel is opened on:" << "\n\tobject path:" << channelPath.value().path() << "\n"; } void MessageFilter::onChatStateChanged(uint contact, uint state) { qDebug() << "contact chat state has changed:"; qDebug() << "\n\tcontact handle:" << contact; QDBusReply contactNameList = conn->InspectHandles(HANDLE_TYPE_CONTACT, QList() << contact); if (!contactNameList.isValid()) { qDebug() << "InspectHandles() returned error:" << contactNameList.error().name() << contactNameList.error().message() << "\n"; } else { if (!contactNameList.value().isEmpty()) { qDebug() << "\tcontact name:" << contactNameList.value().at(0); } } qDebug() << "state:" << state << "\n"; } /* * FIXME * * DTMF - * org.freedesktop.DBus.Error.UnknownMethod * * Password - * org.freedesktop.DBus.Error.UnknownMethod */ void MessageFilter::test_channel_type_streamedmedia() { // create streamed media channel with this contact QStringList contactNameList; contactNameList << "izico0@gmail.com"; QDBusReply > contactHandleList = conn->RequestHandles(HANDLE_TYPE_CONTACT, contactNameList); if (!contactHandleList.isValid()) { qDebug() << "RequestHandles() returned error:" << contactHandleList.error().name() << contactHandleList.error().message() << "\n"; return; } if (contactHandleList.value().isEmpty()) { return; } smContactHandle = contactHandleList.value().at(0); smContactCapabilies = 0; bool isContactCapableOfStreamedMedia = false; /* if we come here too quickly, the capability changed signal of the contact has not been received, so it'll fail to find the streamed media capability of the contact */ // get the capabilities of the contact QDBusReply contactCapabilities = capabilitiesIface->GetCapabilities(contactHandleList.value()); if (!contactCapabilities.isValid()) { qDebug() << "GetCapabilities() returned error:" << contactCapabilities.error().name() << contactCapabilities.error().message() << "\n"; } else { qDebug() << "capabilities of conact" << contactNameList.at(0) << ":"; for (int i = 0; i < contactCapabilities.value().count(); ++i) { qDebug() << "\n\thandle:" << contactCapabilities.value().at(i).contactHandle << "\n\tchannel type:" << contactCapabilities.value().at(i).channelType << "\n\tgeneric flags:" << contactCapabilities.value().at(i).genericFlags << "\n\ttype specific flags:" << contactCapabilities.value().at(i).typeSpecificFlags << "\n"; if ((contactCapabilities.value().at(i).contactHandle == smContactHandle) && (contactCapabilities.value().at(i).channelType == "org.freedesktop.Telepathy.Channel.Type.StreamedMedia")) { isContactCapableOfStreamedMedia = true; smContactCapabilies = contactCapabilities.value().at(i).typeSpecificFlags; } } } // confirm that the contact is capable of streamed media if (!isContactCapableOfStreamedMedia) { qDebug() << contactNameList <<"is not capable of streamed media.\n"; return; } // create the streamed media channel QDBusReply channelPath = conn->RequestChannel("org.freedesktop.Telepathy.Channel.Type.StreamedMedia", HANDLE_TYPE_CONTACT, smContactHandle, true); if (!channelPath.isValid()) { qDebug() << "RequestChannel() returned error:" << channelPath.error().name() << channelPath.error().message() << "\n"; return; } qDebug() << "streamed media channel is opened:" << "\n\tchannel path:" << channelPath.value().path() << "\n\tcontact handle:" << smContactHandle << "\n\tcontact name:" << contactNameList.at(0) << "\n"; setupStreamedMediaChannel(channelPath.value()); // request streams on this channel StreamTypeList streamTypeList; if (CHANNEL_MEDIA_CAPABILITY_AUDIO & smContactCapabilies) { streamTypeList << STREAM_TYPE_AUDIO; } #if 0 if (CHANNEL_MEDIA_CAPABILITY_VIDEO & smContactCapabilies) { streamTypeList << STREAM_TYPE_VIDEO; } #endif QDBusReply streamInfoList = smChannelType->RequestStreams(smContactHandle, streamTypeList); if (!streamInfoList.isValid()) { qDebug() << "RequestStreams() returned error:" << streamInfoList.error().name() << streamInfoList.error().message() << "\n"; return; } if (streamInfoList.value().isEmpty()) { qDebug() << "RequestStreams() returned error:" << "no streams created.\n"; return; } qDebug() << "requested streams:"; foreach (StreamInfo streamInfo, streamInfoList.value()) { qDebug() << "\tidentifier:" << streamInfo.id << "\n\tcontact handle:" << streamInfo.contactHandle << "\n\ttype:" << streamInfo.type << "\n\tstate:" << streamInfo.state << "\n\tdirection:" << streamInfo.direction << "\n\tpending send flags:" << streamInfo.pendingFlags << "\n"; } QDBusReply requestDirectionReply = smChannelType->RequestStreamDirection(streamInfoList.value().at(0).id, STREAM_DIRECTION_SEND); if (!requestDirectionReply.isValid()) { qDebug() << "RequestStreamDirection() returned error:" << requestDirectionReply.error().name() << requestDirectionReply.error().message() << "\n"; } else { qDebug() << "direction of stream is changed:" << "\n\tid:" << streamInfoList.value().at(0).id << "\n\tdirection:" << STREAM_DIRECTION_SEND << "\n"; } // list the currently active streams streamInfoList = smChannelType->ListStreams(); if (!streamInfoList.isValid()) { qDebug() << "ListStreams() returned error:" << streamInfoList.error().name() << streamInfoList.error().message() << "\n"; } else { qDebug() << "currently active streams:"; foreach (StreamInfo streamInfo, streamInfoList.value()) { qDebug() << "\tidentifier:" << streamInfo.id << "\n\tcontact handle:" << streamInfo.contactHandle << "\n\ttype:" << streamInfo.type << "\n\tstate:" << streamInfo.state << "\n\tdirection:" << streamInfo.direction << "\n\tpending send flags:" << streamInfo.pendingFlags << "\n"; } } } void MessageFilter::setupStreamedMediaChannel(const QDBusObjectPath& channelPath) { // create the streamed media channel interface smChannel = new Channel(conn->service(), channelPath.path(), bus, this); connect(smChannel, SIGNAL(Closed()), this, SLOT(onClose())); // create the streamed media channel type interface smChannelType = new ChannelStreamedMedia(conn->service(), channelPath.path(), bus, this); connect(smChannelType, SIGNAL(StreamAdded(uint, uint, uint)), this, SLOT(onStreamAdded(uint, uint, uint))); connect(smChannelType, SIGNAL(StreamDirectionChanged(uint, uint, uint)), this, SLOT(onStreamDirectionChanged(uint, uint, uint))); connect(smChannelType, SIGNAL(StreamError(uint, uint, QString)), this, SLOT(onStreamError(uint, uint, QString))); connect(smChannelType, SIGNAL(StreamRemoved(uint)), this, SLOT(onStreamRemoved(uint))); connect(smChannelType, SIGNAL(StreamStateChanged(uint, uint)), this, SLOT(onStreamStateChanged(uint, uint))); // create the streamed media group interface smChannelGroupIface = new ChannelGroupInterface(conn->service(), channelPath.path(), bus, this); connect(smChannelGroupIface, SIGNAL(GroupFlagsChanged(uint, uint)), this, SLOT(onGroupFlagsChanged(uint, uint))); connect(smChannelGroupIface, SIGNAL(MembersChanged(QString, QList, QList, QList, QList, uint, uint)), this, SLOT(onMembersChanged(QString, QList, QList, QList, QList, uint, uint))); // create the stream engine channel handler interface smChannelHandler = new ChannelHandler(STREAM_ENGINE_IFACE, STREAM_ENGINE_PATH, bus, this); // create the stream engine smStreamEngine = new StreamEngine(STREAM_ENGINE_IFACE, STREAM_ENGINE_PATH, bus, this); connect(smStreamEngine, SIGNAL(Receiving(QDBusObjectPath, uint, bool)), this, SLOT(onReceiving(QDBusObjectPath, uint, bool))); QDBusReply handleChannelReply = smChannelHandler->HandleChannel(conn->service(), QDBusObjectPath(conn->path()), "org.freedesktop.Telepathy.Channel.Type.StreamedMedia", channelPath, 0, 0); if (!handleChannelReply.isValid()) { qDebug() << "HandleChannel() returned error:" << handleChannelReply.error().name() << handleChannelReply.error().message() << "\n"; } else { qDebug() << "streamed channel is now handled by stream engine.\n"; } #if 1 // These interfaces should be handled by stream engine, but here we connect // the signals to see the work flow of stream engine // create streamed media media signalling interface smChannelMediaSignallingIface = new ChannelMediaSignallingInterface(conn->service(), channelPath.path(), bus, this); connect(smChannelMediaSignallingIface, SIGNAL(NewSessionHandler(QDBusObjectPath, QString)), this, SLOT(onNewSessionHandler(QDBusObjectPath, QString))); QDBusReply sessionHandlerList = smChannelMediaSignallingIface->GetSessionHandlers(); if (!sessionHandlerList.isValid()) { qDebug() << "GetSessionHandlers() returned error:" << sessionHandlerList.error().name() << sessionHandlerList.error().message() << "\n"; return; } qDebug() << "currently active session handlers on this channel:"; foreach (SessionHandlerInfo info, sessionHandlerList.value()) { qDebug() << "\tobject path" << info.path.path() << "\n\ttype:" << info.type << "\n"; } #endif } void MessageFilter::onStreamAdded(uint id, uint contactHandle, uint type) { qDebug() << "new stream has been added:" << "\n\tidentifier:" << id << "\n\tcontact handle:" << contactHandle << "\n\tmedia stream type:" << type << "\n"; } void MessageFilter::onStreamDirectionChanged(uint id, uint direction, uint pendingFlags) { qDebug() << "stream direction or pending flags has been changed:" << "\n\tidentifier" << id << "\n\tdirection:" << direction << "\n\tpending flags:" << pendingFlags << "\n"; } void MessageFilter::onStreamError(uint id, uint errno, const QString& message) { qDebug() << "stream error has occured:" << "\n\tidentifier:" << id << "\n\terror number:" << errno << "\n\terror message:" << message << "\n"; } void MessageFilter::onStreamRemoved(uint id) { qDebug() << "one media stream has been removed:" << "\n\tidentifier:" << id << "\n"; } void MessageFilter::onStreamStateChanged(uint id, uint state) { qDebug() << "stream state has changed:" << "\n\tidentifier:" << id << "\n\tstate:" << state << "\n"; } void MessageFilter::onNewSessionHandler(const QDBusObjectPath& path, const QString& type) { qDebug() << "new session handler object has been created by CM:" << "\n\tobject path:" << path.path() << "\n\ttype:" << type << "\n"; // create media session handler smSessionHandler = new MediaSessionHandler(conn->service(), path.path(), bus, this); connect(smSessionHandler, SIGNAL(NewStreamHandler(QDBusObjectPath, uint, uint, uint)), this, SLOT(onNewStreamHandler(QDBusObjectPath, uint, uint, uint))); } void MessageFilter::onNewStreamHandler(const QDBusObjectPath& handlerPath, uint streamId, uint mediaType, uint streamDirection) { qDebug() << "new stream handler has been created by CM:" << "\n\tstream handler path:" << handlerPath.path() << "\n\tstream id:" << streamId << "\n\tmedia stream type:" << mediaType << "\n\tstream direction:" << streamDirection << "\n"; smStreamHandler = new MediaStreamHandler(conn->service(), handlerPath.path(), bus, this); connect(smStreamHandler, SIGNAL(AddRemoteCandidate(QString, org::freedesktop::Telepathy::TransportInfoList)), this, SLOT(onAddRemoteCandidate(QString, org::freedesktop::Telepathy::TransportInfoList))); connect(smStreamHandler, SIGNAL(Close()), this, SLOT(onCloseStream())); connect(smStreamHandler, SIGNAL(RemoveRemoteCandidate(QString)), this, SLOT(onRemoveRemoteCandidate(QString))); connect(smStreamHandler, SIGNAL(SetActiveCandidatePair(QString, QString)), this, SLOT(onSetActiveCandidatePair(QString, QString))); connect(smStreamHandler, SIGNAL(SetRemoteCandidateList(org::freedesktop::Telepathy::CandidateInfoList)), this, SLOT(onSetRemoteCandidateList(org::freedesktop::Telepathy::CandidateInfoList))); connect(smStreamHandler, SIGNAL(SetRemoteCodecs(org::freedesktop::Telepathy::CodecInfoList)), this, SLOT(onSetRemoteCodecs(org::freedesktop::Telepathy::CodecInfoList))); connect(smStreamHandler, SIGNAL(SetStreamPlaying(bool)), this, SLOT(onSetStreamPlaying(bool))); connect(smStreamHandler, SIGNAL(SetStreamSending(bool)), this, SLOT(onSetStreamSending(bool))); connect(smStreamHandler, SIGNAL(StartTelephonyEvent(uchar)), this, SLOT(onStartTelephonyEvent(uchar))); connect(smStreamHandler, SIGNAL(StopTelephonyEvent()), this, SLOT(onStopTelephonyEvent())); } void MessageFilter::onAddRemoteCandidate(const QString& candidateId, const org::freedesktop::Telepathy::TransportInfoList& transportList) { qDebug() << "new remote candidate has been informed:" << "\n\tcandidate id:" << candidateId << "\n\ttransports:"; foreach (TransportInfo t, transportList) { qDebug() << "\t\tcompoment number:" << t.number << "\n\t\tIP address:" << t.ipAddr << "\n\t\tIP port:" << t.port << "\n\t\tbase protocol:" << t.baseProto << "\n\t\tprotocol subtype:" << t.protoSubType << "\n\t\tprotocol profile:" << t.protoProfile << "\n\t\tpreference value:" << t.preference << "\n\t\ttype:" << t.type << "\n\t\tusername:" << t.username << "\n\t\tpassword:" << t.password << "\n"; } } void MessageFilter::onCloseStream() { qDebug() << "one stream has been informed to be close by CM.\n"; } void MessageFilter::onRemoveRemoteCandidate(const QString& candidateId) { qDebug() << "remote candidate" << candidateId << "has been removed.\n"; } void MessageFilter::onSetActiveCandidatePair(const QString& nativeCandidateId, const QString& remoteCandidateId) { qDebug() << "a valid candidate pair" << "(" << nativeCandidateId << ":" << remoteCandidateId << ")" << "has been discovered by the remote end and streaming is in progress.\n"; } void MessageFilter::onSetRemoteCandidateList(const org::freedesktop::Telepathy::CandidateInfoList& remoteCandidateList) { qDebug() << "all the available remote candidates has been informed by CM:"; foreach (CandidateInfo c, remoteCandidateList) { qDebug() << "\tcandidate id:" << c.id << "\n\ttransports:"; foreach (TransportInfo t, c.transportList) { qDebug() << "\t\tcompoment number:" << t.number << "\n\t\tIP address:" << t.ipAddr << "\n\t\tIP port:" << t.port << "\n\t\tbase protocol:" << t.baseProto << "\n\t\tprotocol subtype:" << t.protoSubType << "\n\t\tprotocol profile:" << t.protoProfile << "\n\t\tpreference value:" << t.preference << "\n\t\ttype:" << t.type << "\n\t\tusername:" << t.username << "\n\t\tpassword:" << t.password << "\n"; } } } void MessageFilter::onSetRemoteCodecs(const org::freedesktop::Telepathy::CodecInfoList& codecList) { qDebug() << "supported codecs by remote end has been informed by CM:"; foreach (CodecInfo c, codecList) { qDebug() << "\tid:" << c.id << "\n\tname:" << c.name << "\n\tmedia type:" << c.mediaType << "\n\tclock rate:" << c.clockRate << "\n\tnumber of supported channels:" << c.supportedChannels << "\n\toptional parameters:" << c.parameters << "\n"; } } void MessageFilter::onSetStreamPlaying(bool playing) { qDebug() << "stream playing state has been informed by CM:" << (playing ? "playing" : "stopped") << "\n"; } void MessageFilter::onSetStreamSending(bool sending) { qDebug() << "stream sending state has been informed by CM:" << (sending ? "sending" : "stopped") << "\n"; } void MessageFilter::onStartTelephonyEvent(uchar event) { qDebug() << "CM has informed client to start telephony event" << event << "\n"; } void MessageFilter::onStopTelephonyEvent() { qDebug() << "CM has informed client to stop telephony event.\n"; } void MessageFilter::onReceiving(const QDBusObjectPath& channelPath, uint streamId, bool state) { qDebug() << "stream engine has been receiving stream on:" << "\n\tobject path:" << channelPath.path() << "\n\tstream id:" << streamId << "\n\tstream state:" << state << "\n"; }