AbiCollab* AbiCollabSessionManager::startSession(PD_Document* pDoc, UT_UTF8String& sSessionId, AccountHandler* pAclAccount, bool bLocallyOwned, XAP_Frame* pFrame, const UT_UTF8String& masterDescriptor) { UT_DEBUGMSG(("Starting collaboration session for document with id %s, master descriptor: %s\n", pDoc->getDocUUIDString(), masterDescriptor.utf8_str())); UT_return_val_if_fail(pDoc, NULL); UT_return_val_if_fail(pAclAccount, NULL); if (sSessionId == "") { XAP_App* pApp = XAP_App::getApp(); UT_UUID* pUUID = pApp->getUUIDGenerator()->createUUID(); pUUID->toString(sSessionId); } if (masterDescriptor != "") { // search for a buddy descriptor in the authors list that matches this // descriptor, and make that the active author; if such an author does // not exist, then search for an author with no abicollab property set // at all, and give it this buddy descriptor (ie, we assume that it is // "us", even though it might not always be a valid assumption). int iAuthorId = -1; UT_GenericVector<pp_Author*> authors = pDoc->getAuthors(); pp_Author* pEmptyAuthor = NULL; UT_DEBUGMSG(("Scanning %d authors to see if we recognize this master buddy\n", authors.getItemCount())); for (UT_sint32 i = 0; i < authors.getItemCount(); i++) { pp_Author* pAuthor = authors.getNthItem(i); UT_continue_if_fail(pAuthor); const gchar* szDescriptor = NULL; pAuthor->getProperty("abicollab-descriptor", szDescriptor); if (!szDescriptor) { if (!pEmptyAuthor && !pAuthor->getAttrProp()->hasProperties()) pEmptyAuthor = pAuthor; continue; } if (masterDescriptor != szDescriptor) continue; // yay, we already editted this document ourselves! iAuthorId = pAuthor->getAuthorInt(); pDoc->setMyAuthorInt(iAuthorId); UT_DEBUGMSG(("Found our own author object with descriptior %s, id %d!\n", masterDescriptor.utf8_str(), iAuthorId)); break; } if (iAuthorId == -1) { if (pEmptyAuthor) { // reuse this author object and make it our own iAuthorId = pEmptyAuthor->getAuthorInt(); PP_AttrProp * pPA = pEmptyAuthor->getAttrProp(); pPA->setProperty("abicollab-descriptor", masterDescriptor.utf8_str()); pDoc->setMyAuthorInt(iAuthorId); pDoc->sendChangeAuthorCR(pEmptyAuthor); UT_DEBUGMSG(("Reusing empty author object with id %d, setting descriptor to %s!\n", iAuthorId, masterDescriptor.utf8_str())); } else { UT_DEBUGMSG(("No suitable author found in the document for descriptor %s\n", masterDescriptor.utf8_str())); iAuthorId = pDoc->findFirstFreeAuthorInt(); pp_Author * pA = pDoc->addAuthor(iAuthorId); pDoc->setMyAuthorInt(iAuthorId); PP_AttrProp * pPA = pA->getAttrProp(); pPA->setProperty("abicollab-descriptor", masterDescriptor.utf8_str()); pDoc->sendAddAuthorCR(pA); UT_DEBUGMSG(("Added a new author to the documument with descriptor %s, id %d\n", masterDescriptor.utf8_str(), iAuthorId)); } } } UT_DEBUGMSG(("Creating a new collaboration session with UUID: %s\n", sSessionId.utf8_str())); UT_return_val_if_fail(_setupFrame(&pFrame, pDoc), NULL); AbiCollab* pAbiCollab = new AbiCollab(pDoc, sSessionId, pAclAccount, bLocallyOwned); m_vecSessions.push_back(pAbiCollab); // notify all people we are sharing a new document // FIXME: since we only allow a session to be shared on 1 account, we should // only notify the buddies on that account, instead of notifying the buddies // on all accounts. StartSessionEvent event; event.setBroadcast(true); signal(event); return pAbiCollab; }
bool TelepathyAccountHandler::startSession(PD_Document* pDoc, const std::vector<std::string>& vAcl, AbiCollab** pSession) { UT_DEBUGMSG(("TelepathyAccountHandler::startSession()\n")); UT_return_val_if_fail(pDoc, false); AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager(); UT_return_val_if_fail(pManager, false); // generate a unique session id to use UT_UTF8String sSessionId; UT_UUID* pUUID = XAP_App::getApp()->getUUIDGenerator()->createUUID(); pUUID->toString(sSessionId); DELETEP(pUUID); // start the session already, while we'll continue to setup a // MUC asynchronously below // TODO: we should fill in the in the master buddy descriptor so we can do // proper author coloring and session takeover; we can't do that however, since // the following bugs needs to be fixed first: // // https://bugs.freedesktop.org/show_bug.cgi?id=37631 *pSession = pManager->startSession(pDoc, sSessionId, this, true, NULL, ""); // create a chatroom to hold the session information TelepathyChatroomPtr pChatroom = boost::shared_ptr<TelepathyChatroom>(new TelepathyChatroom(this, NULL, pDoc, sSessionId)); m_chatrooms.push_back(pChatroom); // add the buddies in the acl list to the room invitee list /* std::vector<TelepathyBuddyPtr> buddies = _getBuddies(vAcl); gchar** invitee_ids = reinterpret_cast<gchar**>(malloc(sizeof(gchar*) * vAcl.size()+1)); int i = 0; for (std::vector<TelepathyBuddyPtr>::iterator it = buddies.begin(); it != buddies.end(); it++) { UT_continue_if_fail(*it); invitee_ids[i] = strdup(tp_contact_get_identifier((*it)->getContact())); UT_DEBUGMSG(("Added %s to the invite list\n", invitee_ids[i])); } invitee_ids[vAcl.size()] = NULL; */ _inviteBuddies(pChatroom, vAcl); // use the above code when TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_IDS is usable // a quick hack to determine the account to offer the request on TpAccountManager* manager = tp_account_manager_dup(); UT_return_val_if_fail(manager, false); GList* accounts = tp_account_manager_get_valid_accounts(manager); UT_return_val_if_fail(accounts, false); // TODO: make sure the accounts are ready TpAccount* selected_account = NULL; for (GList* account = accounts; account; account = account->next) { selected_account = TP_ACCOUNT(account->data); break; } UT_return_val_if_fail(selected_account, false); g_list_free(accounts); // determine the room target id std::string target_id = sSessionId.utf8_str(); std::string conference_server = getProperty("conference_server"); if (conference_server != "") target_id += "@" + conference_server; UT_DEBUGMSG(("Using room target ID: %s\n", target_id.c_str())); // create a anonymous MUC channel request GHashTable* props = tp_asv_new ( TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, TP_TYPE_HANDLE, TP_HANDLE_TYPE_ROOM, TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, target_id.c_str(), TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME, G_TYPE_STRING, INTERFACE, /* * Enable TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_IDS if you want to use * anonymous MUCs. We can't use it right now, anonymous DBUS_TUBE MUCs are not implemented yet. * Remove the HANDLE_TYPE and TARGET_ID when you enable this. * * See https://bugs.freedesktop.org/show_bug.cgi?id=37630 for details. * * TP_PROP_CHANNEL_INTERFACE_CONFERENCE_INITIAL_INVITEE_IDS, G_TYPE_STRV, invitee_ids, */ NULL); TpAccountChannelRequest * channel_request = tp_account_channel_request_new(selected_account, props, TP_USER_ACTION_TIME_NOT_USER_ACTION); UT_return_val_if_fail(channel_request, false); g_hash_table_destroy (props); // TODO: free invitee_ids tp_account_channel_request_create_and_handle_channel_async(channel_request, NULL, muc_channel_ready_cb, pChatroom.get()); return true; }