mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
swarm: follow user preference for hosting conferences
This avoid mobile phone to host conferences for others unless explicitly authorized by the user. Clients can show it via the "hostConference" conversation's preference. Documentation: https://docs.jami.net/technical/swarm.html#call-in-swarm GitLab: #312 Change-Id: I9bbd3e394cd1b3bcfd4a3120d9023a5ed686303d
This commit is contained in:
@ -52,6 +52,10 @@ static constexpr const char* CONVERSATIONID = "conversationId";
|
||||
static constexpr const char* METADATAS = "metadatas";
|
||||
} // namespace ConversationMapKeys
|
||||
|
||||
namespace ConversationPreferences {
|
||||
static constexpr const char* HOST_CONFERENCES = "hostConferences";
|
||||
}
|
||||
|
||||
/**
|
||||
* A ConversationRequest is a request which corresponds to a trust request, but for conversations
|
||||
* It's signed by the sender and contains the members list, the conversationId, and the metadatas
|
||||
|
@ -2043,13 +2043,9 @@ ConversationModule::call(const std::string& url,
|
||||
return;
|
||||
}
|
||||
conversationId = parameters[0];
|
||||
JAMI_ERR("@@@ %s", conversationId.c_str());
|
||||
uri = parameters[1];
|
||||
JAMI_ERR("@@@ %s", uri.c_str());
|
||||
deviceId = parameters[2];
|
||||
JAMI_ERR("@@@ %s", deviceId.c_str());
|
||||
confId = parameters[3];
|
||||
JAMI_ERR("@@@ %s", confId.c_str());
|
||||
}
|
||||
|
||||
std::string callUri;
|
||||
|
@ -164,7 +164,7 @@ void
|
||||
setState(const std::string& accountID, const State migrationState)
|
||||
{
|
||||
emitSignal<libjami::ConfigurationSignal::MigrationEnded>(accountID,
|
||||
mapStateNumberToString(migrationState));
|
||||
mapStateNumberToString(migrationState));
|
||||
}
|
||||
|
||||
} // namespace Migration
|
||||
@ -532,14 +532,32 @@ JamiAccount::handleIncomingConversationCall(const std::string& callId,
|
||||
if (getUsername() != accountUri || currentDeviceId() != deviceId)
|
||||
return;
|
||||
|
||||
auto isNotHosting = !convModule()->isHosting(conversationId, confId);
|
||||
auto preferences = convModule()->getConversationPreferences(conversationId);
|
||||
auto canHost = true;
|
||||
#if defined(__ANDROID__) || defined(__APPLE__)
|
||||
// By default, mobile devices SHOULD NOT host conferences.
|
||||
canHost = false;
|
||||
#endif
|
||||
auto itPref = preferences.find(ConversationPreferences::HOST_CONFERENCES);
|
||||
if (itPref != preferences.end()) {
|
||||
canHost = itPref->second == TRUE_STR;
|
||||
}
|
||||
|
||||
auto call = getCall(callId);
|
||||
if (!call) {
|
||||
JAMI_ERR("Call %s not found", callId.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNotHosting && !canHost) {
|
||||
JAMI_DBG("Request for hosting a conference declined");
|
||||
Manager::instance().hangupCall(getAccountID(), callId);
|
||||
return;
|
||||
}
|
||||
Manager::instance().answerCall(*call);
|
||||
|
||||
if (!convModule()->isHosting(conversationId, confId)) {
|
||||
if (isNotHosting) {
|
||||
// Create conference and host it.
|
||||
convModule()->hostConference(conversationId, confId, callId);
|
||||
if (auto conf = getConference(confId))
|
||||
@ -904,7 +922,7 @@ JamiAccount::changeArchivePassword(const std::string& password_old, const std::s
|
||||
JAMI_ERR("[Account %s] Can't change archive password", getAccountID().c_str());
|
||||
return false;
|
||||
}
|
||||
editConfig([&](JamiAccountConfig& config){
|
||||
editConfig([&](JamiAccountConfig& config) {
|
||||
config.archiveHasPassword = not password_new.empty();
|
||||
});
|
||||
} catch (const std::exception& ex) {
|
||||
@ -912,17 +930,15 @@ JamiAccount::changeArchivePassword(const std::string& password_old, const std::s
|
||||
getAccountID().c_str(),
|
||||
ex.what());
|
||||
if (password_old.empty()) {
|
||||
editConfig([&](JamiAccountConfig& config){
|
||||
config.archiveHasPassword = true;
|
||||
});
|
||||
editConfig([&](JamiAccountConfig& config) { config.archiveHasPassword = true; });
|
||||
emitSignal<libjami::ConfigurationSignal::AccountDetailsChanged>(getAccountID(),
|
||||
getAccountDetails());
|
||||
getAccountDetails());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (password_old != password_new)
|
||||
emitSignal<libjami::ConfigurationSignal::AccountDetailsChanged>(getAccountID(),
|
||||
getAccountDetails());
|
||||
getAccountDetails());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -979,7 +995,7 @@ JamiAccount::setValidity(const std::string& pwd, const dht::InfoHash& id, int64_
|
||||
void
|
||||
JamiAccount::forceReloadAccount()
|
||||
{
|
||||
editConfig([&](JamiAccountConfig& conf){
|
||||
editConfig([&](JamiAccountConfig& conf) {
|
||||
conf.receipt.clear();
|
||||
conf.receiptSignature.clear();
|
||||
});
|
||||
@ -1026,8 +1042,9 @@ JamiAccount::revokeDevice(const std::string& password, const std::string& device
|
||||
return accountManager_
|
||||
->revokeDevice(password, device, [this, device](AccountManager::RevokeDeviceResult result) {
|
||||
emitSignal<libjami::ConfigurationSignal::DeviceRevocationEnded>(getAccountID(),
|
||||
device,
|
||||
static_cast<int>(result));
|
||||
device,
|
||||
static_cast<int>(
|
||||
result));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@ -1078,8 +1095,8 @@ JamiAccount::loadAccount(const std::string& archive_password,
|
||||
}
|
||||
// Update client.
|
||||
emitSignal<libjami::ConfigurationSignal::ContactRemoved>(shared->getAccountID(),
|
||||
uri,
|
||||
banned);
|
||||
uri,
|
||||
banned);
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -1093,10 +1110,10 @@ JamiAccount::loadAccount(const std::string& archive_password,
|
||||
if (conversationId.empty()) {
|
||||
// Old path
|
||||
emitSignal<libjami::ConfigurationSignal::IncomingTrustRequest>(getAccountID(),
|
||||
conversationId,
|
||||
uri,
|
||||
payload,
|
||||
received);
|
||||
conversationId,
|
||||
uri,
|
||||
payload,
|
||||
received);
|
||||
return;
|
||||
}
|
||||
// Here account can be initializing
|
||||
@ -1232,18 +1249,17 @@ JamiAccount::loadAccount(const std::string& archive_password,
|
||||
ip_utils::getDeviceName(),
|
||||
std::move(creds),
|
||||
[this, migrating, hasPassword](const AccountInfo& info,
|
||||
const std::map<std::string, std::string>& config,
|
||||
std::string&& receipt,
|
||||
std::vector<uint8_t>&& receipt_signature) {
|
||||
const std::map<std::string, std::string>& config,
|
||||
std::string&& receipt,
|
||||
std::vector<uint8_t>&& receipt_signature) {
|
||||
JAMI_INFO("[Account %s] Auth success!", getAccountID().c_str());
|
||||
|
||||
fileutils::check_dir(idPath_.c_str(), 0700);
|
||||
|
||||
auto id = info.identity;
|
||||
editConfig([&](JamiAccountConfig& conf){
|
||||
std::tie(conf.tlsPrivateKeyFile, conf.tlsCertificateFile) = saveIdentity(id,
|
||||
idPath_,
|
||||
DEVICE_ID_PATH);
|
||||
editConfig([&](JamiAccountConfig& conf) {
|
||||
std::tie(conf.tlsPrivateKeyFile, conf.tlsCertificateFile)
|
||||
= saveIdentity(id, idPath_, DEVICE_ID_PATH);
|
||||
conf.tlsPassword = {};
|
||||
conf.archiveHasPassword = hasPassword;
|
||||
if (not conf.managerUri.empty()) {
|
||||
@ -1253,11 +1269,13 @@ JamiAccount::loadAccount(const std::string& archive_password,
|
||||
conf.username = info.accountId;
|
||||
conf.deviceName = accountManager_->getAccountDeviceName();
|
||||
|
||||
auto nameServerIt = config.find(libjami::Account::ConfProperties::RingNS::URI);
|
||||
auto nameServerIt = config.find(
|
||||
libjami::Account::ConfProperties::RingNS::URI);
|
||||
if (nameServerIt != config.end() && !nameServerIt->second.empty()) {
|
||||
conf.nameServer = nameServerIt->second;
|
||||
}
|
||||
auto displayNameIt = config.find(libjami::Account::ConfProperties::DISPLAYNAME);
|
||||
auto displayNameIt = config.find(
|
||||
libjami::Account::ConfProperties::DISPLAYNAME);
|
||||
if (displayNameIt != config.end() && !displayNameIt->second.empty()) {
|
||||
conf.displayName = displayNameIt->second;
|
||||
}
|
||||
@ -1270,9 +1288,8 @@ JamiAccount::loadAccount(const std::string& archive_password,
|
||||
Migration::setState(getAccountID(), Migration::State::SUCCESS);
|
||||
}
|
||||
if (not info.photo.empty() or not config_->displayName.empty())
|
||||
emitSignal<libjami::ConfigurationSignal::AccountProfileReceived>(getAccountID(),
|
||||
config_->displayName,
|
||||
info.photo);
|
||||
emitSignal<libjami::ConfigurationSignal::AccountProfileReceived>(
|
||||
getAccountID(), config_->displayName, info.photo);
|
||||
setRegistrationState(RegistrationState::UNREGISTERED);
|
||||
convModule()->loadConversations();
|
||||
doRegister();
|
||||
@ -1350,9 +1367,9 @@ JamiAccount::lookupAddress(const std::string& addr)
|
||||
accountManager_->lookupAddress(
|
||||
addr, [acc, addr](const std::string& result, NameDirectory::Response response) {
|
||||
emitSignal<libjami::ConfigurationSignal::RegisteredNameFound>(acc,
|
||||
(int) response,
|
||||
addr,
|
||||
result);
|
||||
(int) response,
|
||||
addr,
|
||||
result);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1379,9 +1396,8 @@ JamiAccount::registerName(const std::string& password, const std::string& name)
|
||||
if (response == NameDirectory::RegistrationResponse::success) {
|
||||
if (auto this_ = w.lock()) {
|
||||
this_->registeredName_ = name;
|
||||
this_->editConfig([&](JamiAccountConfig& config){
|
||||
config.registeredName = name;
|
||||
});
|
||||
this_->editConfig(
|
||||
[&](JamiAccountConfig& config) { config.registeredName = name; });
|
||||
emitSignal<libjami::ConfigurationSignal::VolatileDetailsChanged>(
|
||||
this_->accountID_, this_->getVolatileAccountDetails());
|
||||
}
|
||||
@ -1400,9 +1416,9 @@ JamiAccount::searchUser(const std::string& query)
|
||||
[acc = getAccountID(), query](const jami::NameDirectory::SearchResult& result,
|
||||
jami::NameDirectory::Response response) {
|
||||
jami::emitSignal<libjami::ConfigurationSignal::UserSearchEnded>(acc,
|
||||
(int) response,
|
||||
query,
|
||||
result);
|
||||
(int) response,
|
||||
query,
|
||||
result);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
@ -1705,9 +1721,9 @@ JamiAccount::onTrackedBuddyOffline(const dht::InfoHash& contactId)
|
||||
{
|
||||
JAMI_DBG("Buddy %s offline", contactId.toString().c_str());
|
||||
emitSignal<libjami::PresenceSignal::NewBuddyNotification>(getAccountID(),
|
||||
contactId.toString(),
|
||||
0,
|
||||
"");
|
||||
contactId.toString(),
|
||||
0,
|
||||
"");
|
||||
}
|
||||
|
||||
void
|
||||
@ -1743,18 +1759,16 @@ JamiAccount::doRegister_()
|
||||
if (response == NameDirectory::Response::found) {
|
||||
if (this_->registeredName_ != result) {
|
||||
this_->registeredName_ = result;
|
||||
this_->editConfig([&](JamiAccountConfig& config){
|
||||
config.registeredName = result;
|
||||
});
|
||||
this_->editConfig(
|
||||
[&](JamiAccountConfig& config) { config.registeredName = result; });
|
||||
emitSignal<libjami::ConfigurationSignal::VolatileDetailsChanged>(
|
||||
this_->accountID_, this_->getVolatileAccountDetails());
|
||||
}
|
||||
} else if (response == NameDirectory::Response::notFound) {
|
||||
if (not this_->registeredName_.empty()) {
|
||||
this_->registeredName_.clear();
|
||||
this_->editConfig([&](JamiAccountConfig& config){
|
||||
config.registeredName.clear();
|
||||
});
|
||||
this_->editConfig(
|
||||
[&](JamiAccountConfig& config) { config.registeredName.clear(); });
|
||||
emitSignal<libjami::ConfigurationSignal::VolatileDetailsChanged>(
|
||||
this_->accountID_, this_->getVolatileAccountDetails());
|
||||
}
|
||||
@ -1824,8 +1838,8 @@ JamiAccount::doRegister_()
|
||||
auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch())
|
||||
.count();
|
||||
jami::emitSignal<libjami::ConfigurationSignal::MessageSend>(std::to_string(now) + " "
|
||||
+ std::string(tmp));
|
||||
jami::emitSignal<libjami::ConfigurationSignal::MessageSend>(
|
||||
std::to_string(now) + " " + std::string(tmp));
|
||||
};
|
||||
context.logger = std::make_shared<dht::Logger>(log_all, log_all, silent);
|
||||
#else
|
||||
@ -1995,8 +2009,8 @@ JamiAccount::doRegister_()
|
||||
if (isVCard)
|
||||
cb = [peerId, accountId = getAccountID()](const std::string& path) {
|
||||
emitSignal<libjami::ConfigurationSignal::ProfileReceived>(accountId,
|
||||
peerId,
|
||||
path);
|
||||
peerId,
|
||||
path);
|
||||
};
|
||||
|
||||
libjami::DataTransferInfo info;
|
||||
@ -2174,21 +2188,23 @@ JamiAccount::convModule()
|
||||
cb({});
|
||||
return;
|
||||
}
|
||||
shared->connectionManager_
|
||||
->connectDevice(DeviceId(deviceId),
|
||||
"git://" + deviceId + "/" + convId,
|
||||
[shared, cb, convId](std::shared_ptr<ChannelSocket> socket,
|
||||
const DeviceId&) {
|
||||
if (socket) {
|
||||
socket->onShutdown(
|
||||
[shared, deviceId = socket->deviceId(), convId] {
|
||||
shared->removeGitSocket(deviceId, convId);
|
||||
});
|
||||
if (!cb(socket))
|
||||
socket->shutdown();
|
||||
} else
|
||||
cb({});
|
||||
}, false, false, type);
|
||||
shared->connectionManager_->connectDevice(
|
||||
DeviceId(deviceId),
|
||||
"git://" + deviceId + "/" + convId,
|
||||
[shared, cb, convId](std::shared_ptr<ChannelSocket> socket,
|
||||
const DeviceId&) {
|
||||
if (socket) {
|
||||
socket->onShutdown([shared, deviceId = socket->deviceId(), convId] {
|
||||
shared->removeGitSocket(deviceId, convId);
|
||||
});
|
||||
if (!cb(socket))
|
||||
socket->shutdown();
|
||||
} else
|
||||
cb({});
|
||||
},
|
||||
false,
|
||||
false,
|
||||
type);
|
||||
});
|
||||
},
|
||||
[this](auto&& convId, auto&& contactUri, bool accept) {
|
||||
@ -2347,11 +2363,10 @@ JamiAccount::setCertificateStatus(const std::string& cert_id,
|
||||
{
|
||||
bool done = accountManager_ ? accountManager_->setCertificateStatus(cert_id, status) : false;
|
||||
if (done) {
|
||||
dht_->findCertificate(dht::InfoHash(cert_id), [](const std::shared_ptr<dht::crypto::Certificate>& crt) {});
|
||||
emitSignal<libjami::ConfigurationSignal::CertificateStateChanged>(getAccountID(),
|
||||
cert_id,
|
||||
tls::TrustStore::statusToStr(
|
||||
status));
|
||||
dht_->findCertificate(dht::InfoHash(cert_id),
|
||||
[](const std::shared_ptr<dht::crypto::Certificate>& crt) {});
|
||||
emitSignal<libjami::ConfigurationSignal::CertificateStateChanged>(
|
||||
getAccountID(), cert_id, tls::TrustStore::statusToStr(status));
|
||||
}
|
||||
return done;
|
||||
}
|
||||
@ -2551,9 +2566,7 @@ JamiAccount::loadCachedProxyServer(std::function<void(const std::string& proxy)>
|
||||
{
|
||||
const auto& conf = config();
|
||||
if (conf.proxyEnabled and proxyServerCached_.empty()) {
|
||||
JAMI_DEBUG("[Account {:s}] loading DHT proxy URL: {:s}",
|
||||
getAccountID(),
|
||||
conf.proxyListUrl);
|
||||
JAMI_DEBUG("[Account {:s}] loading DHT proxy URL: {:s}", getAccountID(), conf.proxyListUrl);
|
||||
if (conf.proxyListUrl.empty()) {
|
||||
cb(getDhtProxyServer(conf.proxyServer));
|
||||
} else {
|
||||
@ -3013,19 +3026,24 @@ JamiAccount::sendMessage(const std::string& to,
|
||||
ctx->confirmation = confirm;
|
||||
|
||||
try {
|
||||
auto res = sendSIPMessage(
|
||||
conn, to, ctx.release(), token, payloads, [](void* token, pjsip_event* event) {
|
||||
std::shared_ptr<TextMessageCtx> c {(TextMessageCtx*) token};
|
||||
auto code = event->body.tsx_state.tsx->status_code;
|
||||
runOnMainThread([c=std::move(c), code]() {
|
||||
if (c) {
|
||||
auto acc = c->acc.lock();
|
||||
if (not acc)
|
||||
return;
|
||||
acc->onSIPMessageSent(std::move(c), code);
|
||||
}
|
||||
});
|
||||
});
|
||||
auto res = sendSIPMessage(conn,
|
||||
to,
|
||||
ctx.release(),
|
||||
token,
|
||||
payloads,
|
||||
[](void* token, pjsip_event* event) {
|
||||
std::shared_ptr<TextMessageCtx> c {
|
||||
(TextMessageCtx*) token};
|
||||
auto code = event->body.tsx_state.tsx->status_code;
|
||||
runOnMainThread([c = std::move(c), code]() {
|
||||
if (c) {
|
||||
auto acc = c->acc.lock();
|
||||
if (not acc)
|
||||
return;
|
||||
acc->onSIPMessageSent(std::move(c), code);
|
||||
}
|
||||
});
|
||||
});
|
||||
if (!res) {
|
||||
if (!onlyConnected)
|
||||
messageEngine_.onMessageSent(to, token, false);
|
||||
@ -3163,7 +3181,8 @@ JamiAccount::sendMessage(const std::string& to,
|
||||
std::unique_lock<std::mutex> l(confirm->lock);
|
||||
if (not confirm->replied) {
|
||||
if (auto this_ = w.lock()) {
|
||||
JAMI_DBG() << "[Account " << this_->getAccountID() << "] [message " << token << "] Timeout";
|
||||
JAMI_DBG() << "[Account " << this_->getAccountID() << "] [message " << token
|
||||
<< "] Timeout";
|
||||
for (auto& t : confirm->listenTokens)
|
||||
this_->dht_->cancelListen(t.first, std::move(t.second));
|
||||
confirm->listenTokens.clear();
|
||||
@ -3214,9 +3233,9 @@ JamiAccount::onIsComposing(const std::string& conversationId,
|
||||
try {
|
||||
const std::string fromUri {parseJamiUri(peer)};
|
||||
emitSignal<libjami::ConfigurationSignal::ComposingStatusChanged>(accountID_,
|
||||
conversationId,
|
||||
peer,
|
||||
isWriting ? 1 : 0);
|
||||
conversationId,
|
||||
peer,
|
||||
isWriting ? 1 : 0);
|
||||
} catch (...) {
|
||||
JAMI_ERR("[Account %s] Can't parse URI: %s", getAccountID().c_str(), peer.c_str());
|
||||
}
|
||||
@ -3379,9 +3398,10 @@ JamiAccount::startAccountDiscovery()
|
||||
v.accountId.to_c_str());
|
||||
// Send Added Peer and corrsponding accoundID
|
||||
emitSignal<libjami::PresenceSignal::NearbyPeerNotification>(getAccountID(),
|
||||
v.accountId.toString(),
|
||||
0,
|
||||
v.displayName);
|
||||
v.accountId
|
||||
.toString(),
|
||||
0,
|
||||
v.displayName);
|
||||
}
|
||||
dp.cleanupTask = Manager::instance().scheduler().scheduleIn(
|
||||
[w = weak(), p = v.accountId, a = v.displayName] {
|
||||
@ -3726,7 +3746,7 @@ JamiAccount::requestSIPConnection(const std::string& peerId,
|
||||
deviceId,
|
||||
"sip",
|
||||
[w = weak(), id = std::move(id), pc = std::move(pc)](std::shared_ptr<ChannelSocket> socket,
|
||||
const DeviceId&) {
|
||||
const DeviceId&) {
|
||||
if (socket)
|
||||
return;
|
||||
auto shared = w.lock();
|
||||
@ -3920,7 +3940,7 @@ JamiAccount::cacheSIPConnection(std::shared_ptr<ChannelSocket>&& socket,
|
||||
|
||||
// Convert to SIP transport
|
||||
auto onShutdown = [w = weak(), peerId, key, socket]() {
|
||||
runOnMainThread([w=std::move(w), peerId, key, socket] {
|
||||
runOnMainThread([w = std::move(w), peerId, key, socket] {
|
||||
auto shared = w.lock();
|
||||
if (!shared)
|
||||
return;
|
||||
@ -4051,10 +4071,8 @@ JamiAccount::sendFile(const std::string& conversationId,
|
||||
std::move(value),
|
||||
replyTo,
|
||||
true,
|
||||
[accId = shared->getAccountID(),
|
||||
conversationId,
|
||||
tid,
|
||||
path](const std::string& commitId) {
|
||||
[accId = shared->getAccountID(), conversationId, tid, path](
|
||||
const std::string& commitId) {
|
||||
// Create a symlink to answer to re-ask
|
||||
auto filelinkPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR
|
||||
+ accId + DIR_SEPARATOR_STR
|
||||
|
@ -39,6 +39,7 @@ struct ConvData
|
||||
{
|
||||
std::string id {};
|
||||
bool requestReceived {false};
|
||||
bool needsHost {false};
|
||||
bool conferenceChanged {false};
|
||||
bool conferenceRemoved {false};
|
||||
std::string hostState {};
|
||||
@ -78,6 +79,8 @@ private:
|
||||
void testJoinFinishedCallForbidden();
|
||||
void testUsePreference();
|
||||
void testJoinWhileActiveCall();
|
||||
void testCallSelfIfDefaultHost();
|
||||
void testNeedsHost();
|
||||
|
||||
CPPUNIT_TEST_SUITE(ConversationCallTest);
|
||||
CPPUNIT_TEST(testActiveCalls);
|
||||
@ -88,6 +91,8 @@ private:
|
||||
CPPUNIT_TEST(testJoinFinishedCallForbidden);
|
||||
CPPUNIT_TEST(testUsePreference);
|
||||
CPPUNIT_TEST(testJoinWhileActiveCall);
|
||||
CPPUNIT_TEST(testCallSelfIfDefaultHost);
|
||||
CPPUNIT_TEST(testNeedsHost);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
};
|
||||
|
||||
@ -98,7 +103,7 @@ ConversationCallTest::setUp()
|
||||
{
|
||||
// Init daemon
|
||||
libjami::init(
|
||||
libjami::InitFlag(libjami::libjami_FLAG_DEBUG | libjami::libjami_FLAG_CONSOLE_LOG));
|
||||
libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG));
|
||||
if (not Manager::instance().initialized)
|
||||
CPPUNIT_ASSERT(libjami::start("jami-sample.yml"));
|
||||
|
||||
@ -173,6 +178,18 @@ ConversationCallTest::connectSignals()
|
||||
carlaData_.requestReceived = true;
|
||||
cv.notify_one();
|
||||
}));
|
||||
confHandlers.insert(libjami::exportable_callback<libjami::ConfigurationSignal::NeedsHost>(
|
||||
[&](const std::string& accountId, const std::string& /*conversationId*/) {
|
||||
if (accountId == aliceId)
|
||||
aliceData_.needsHost = true;
|
||||
if (accountId == bobId)
|
||||
bobData_.needsHost = true;
|
||||
if (accountId == bob2Id)
|
||||
bob2Data_.needsHost = true;
|
||||
if (accountId == carlaId)
|
||||
carlaData_.needsHost = true;
|
||||
cv.notify_one();
|
||||
}));
|
||||
confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::ConferenceChanged>(
|
||||
[&](const std::string& accountId, const std::string&, const std::string&) {
|
||||
if (accountId == aliceId)
|
||||
@ -320,12 +337,12 @@ ConversationCallTest::testActiveCalls3Peers()
|
||||
return lastCommitIsCall(aliceData_) && lastCommitIsCall(bobData_)
|
||||
&& lastCommitIsCall(carlaData_);
|
||||
});
|
||||
|
||||
auto confId = bobData_.messages.rbegin()->at("confId");
|
||||
auto destination = fmt::format("rdv:{}/{}/{}/{}",
|
||||
bobData_.id,
|
||||
bobData_.messages.rbegin()->at("uri"),
|
||||
bobData_.messages.rbegin()->at("device"),
|
||||
bobData_.messages.rbegin()->at("confId"));
|
||||
confId);
|
||||
|
||||
aliceData_.conferenceChanged = false;
|
||||
libjami::placeCallWithMedia(bobId, destination, {});
|
||||
@ -339,7 +356,7 @@ ConversationCallTest::testActiveCalls3Peers()
|
||||
});
|
||||
|
||||
// get 3 participants
|
||||
auto callList = libjami::getParticipantList(aliceId, bobData_.messages.rbegin()->at("confId"));
|
||||
auto callList = libjami::getParticipantList(aliceId, confId);
|
||||
CPPUNIT_ASSERT(callList.size() == 3);
|
||||
|
||||
// get active calls = 1
|
||||
@ -349,7 +366,7 @@ ConversationCallTest::testActiveCalls3Peers()
|
||||
aliceData_.messages.clear();
|
||||
bobData_.messages.clear();
|
||||
carlaData_.messages.clear();
|
||||
Manager::instance().hangupCall(aliceId, callId);
|
||||
Manager::instance().hangupConference(aliceId, confId);
|
||||
|
||||
// should get message
|
||||
cv.wait_for(lk, 30s, [&]() {
|
||||
@ -417,7 +434,7 @@ ConversationCallTest::testRejoinCall()
|
||||
bobData_.id,
|
||||
bobData_.messages.rbegin()->at("uri"),
|
||||
bobData_.messages.rbegin()->at("device"),
|
||||
bobData_.messages.rbegin()->at("confId"));
|
||||
confId);
|
||||
|
||||
aliceData_.conferenceChanged = false;
|
||||
auto bobCall = libjami::placeCallWithMedia(bobId, destination, {});
|
||||
@ -457,7 +474,7 @@ ConversationCallTest::testRejoinCall()
|
||||
aliceData_.messages.clear();
|
||||
bobData_.messages.clear();
|
||||
carlaData_.messages.clear();
|
||||
Manager::instance().hangupCall(aliceId, callId);
|
||||
Manager::instance().hangupConference(aliceId, confId);
|
||||
|
||||
// should get message
|
||||
cv.wait_for(lk, 30s, [&]() {
|
||||
@ -821,11 +838,110 @@ ConversationCallTest::testJoinWhileActiveCall()
|
||||
aliceData_.messages.clear();
|
||||
bobData_.messages.clear();
|
||||
aliceData_.conferenceChanged = false;
|
||||
Manager::instance().hangupCall(bobId, bobCallId);
|
||||
Manager::instance().hangupCall(aliceId, callId);
|
||||
|
||||
CPPUNIT_ASSERT(!cv.wait_for(lk, 10s, [&]() { return aliceData_.conferenceRemoved; }));
|
||||
}
|
||||
|
||||
void
|
||||
ConversationCallTest::testCallSelfIfDefaultHost()
|
||||
{
|
||||
enableCarla();
|
||||
connectSignals();
|
||||
auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
|
||||
auto aliceUri = aliceAccount->getUsername();
|
||||
auto aliceDevice = std::string(aliceAccount->currentDeviceId());
|
||||
auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
|
||||
auto bobUri = bobAccount->getUsername();
|
||||
// Start conversation
|
||||
libjami::startConversation(aliceId);
|
||||
cv.wait_for(lk, 30s, [&]() { return !aliceData_.id.empty(); });
|
||||
libjami::addConversationMember(aliceId, aliceData_.id, bobUri);
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bobData_.requestReceived; }));
|
||||
aliceData_.messages.clear();
|
||||
libjami::acceptConversationRequest(bobId, aliceData_.id);
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
|
||||
return !bobData_.id.empty() && !aliceData_.messages.empty();
|
||||
}));
|
||||
// Update preferences
|
||||
aliceData_.messages.clear();
|
||||
bobData_.messages.clear();
|
||||
auto lastCommitIsProfile = [&](const auto& data) {
|
||||
return !data.messages.empty()
|
||||
&& data.messages.rbegin()->at("type") == "application/update-profile";
|
||||
};
|
||||
libjami::updateConversationInfos(aliceId,
|
||||
aliceData_.id,
|
||||
std::map<std::string, std::string> {
|
||||
{"rdvAccount", aliceUri},
|
||||
{"rdvDevice", aliceDevice},
|
||||
});
|
||||
// should get message
|
||||
cv.wait_for(lk, 30s, [&]() {
|
||||
return lastCommitIsProfile(aliceData_) && lastCommitIsProfile(bobData_);
|
||||
});
|
||||
// start call
|
||||
aliceData_.messages.clear();
|
||||
bobData_.messages.clear();
|
||||
auto callId = libjami::placeCallWithMedia(aliceId, "swarm:" + aliceData_.id, {});
|
||||
auto lastCommitIsCall = [&](const auto& data) {
|
||||
return !data.messages.empty()
|
||||
&& data.messages.rbegin()->at("type") == "application/call-history+json";
|
||||
};
|
||||
// should get message
|
||||
cv.wait_for(lk, 30s, [&]() {
|
||||
return lastCommitIsCall(aliceData_) && lastCommitIsCall(bobData_);
|
||||
});
|
||||
auto confId = aliceData_.messages.rbegin()->at("confId");
|
||||
// Alice should be the host
|
||||
CPPUNIT_ASSERT(aliceAccount->getConference(confId));
|
||||
Manager::instance().hangupConference(aliceId, confId);
|
||||
}
|
||||
void
|
||||
ConversationCallTest::testNeedsHost()
|
||||
{
|
||||
enableCarla();
|
||||
connectSignals();
|
||||
auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
|
||||
auto aliceUri = aliceAccount->getUsername();
|
||||
auto aliceDevice = std::string(aliceAccount->currentDeviceId());
|
||||
auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
|
||||
auto bobUri = bobAccount->getUsername();
|
||||
// Start conversation
|
||||
libjami::startConversation(aliceId);
|
||||
cv.wait_for(lk, 30s, [&]() { return !aliceData_.id.empty(); });
|
||||
libjami::addConversationMember(aliceId, aliceData_.id, bobUri);
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bobData_.requestReceived; }));
|
||||
aliceData_.messages.clear();
|
||||
libjami::acceptConversationRequest(bobId, aliceData_.id);
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
|
||||
return !bobData_.id.empty() && !aliceData_.messages.empty();
|
||||
}));
|
||||
// Update preferences
|
||||
aliceData_.messages.clear();
|
||||
bobData_.messages.clear();
|
||||
auto lastCommitIsProfile = [&](const auto& data) {
|
||||
return !data.messages.empty()
|
||||
&& data.messages.rbegin()->at("type") == "application/update-profile";
|
||||
};
|
||||
libjami::updateConversationInfos(aliceId,
|
||||
aliceData_.id,
|
||||
std::map<std::string, std::string> {
|
||||
{"rdvAccount", aliceUri},
|
||||
{"rdvDevice", aliceDevice},
|
||||
});
|
||||
// should get message
|
||||
cv.wait_for(lk, 30s, [&]() {
|
||||
return lastCommitIsProfile(aliceData_) && lastCommitIsProfile(bobData_);
|
||||
});
|
||||
// Disable Host
|
||||
Manager::instance().sendRegister(aliceId, false);
|
||||
// start call
|
||||
auto callId = libjami::placeCallWithMedia(bobId, "swarm:" + aliceData_.id, {});
|
||||
// should get message
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bobData_.needsHost; }));
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace jami
|
||||
|
||||
|
Reference in New Issue
Block a user