Commit d929ec32 authored by atraczyk's avatar atraczyk Committed by Nicolas Jager
Browse files

dring interface: use queue of lambdas to wrap API calls



- changes the client-to-daemon interface to use a queue of lambdas
  instead of a enumerated task type parsed with a switch statement

- resulting code is: less duplicated, easier to read and modify

- better seperates the UI thread code

Change-Id: Id13defbab9ba36c3a2e51b3845de59ddd6667aaf
Reviewed-by: default avatarNicolas Jäger <nicolas.jager@savoirfairelinux.com>
parent deeeab47
......@@ -60,7 +60,7 @@ AccountsViewModel::raiseUnreadContactRequest()
newUnreadContactRequest();
}
void
Account^
AccountsViewModel::addRingAccount( std::string& alias,
std::string& ringID,
std::string& accountID,
......@@ -92,9 +92,10 @@ AccountsViewModel::addRingAccount( std::string& alias,
accountsList_->InsertAt(0, account);
contactListModels_->Insert(account->accountID_, ref new ContactListModel(account->accountID_));
accountAdded(account);
return account;
}
void
Account^
AccountsViewModel::addSipAccount( std::string& alias,
std::string& accountID,
bool active,
......@@ -121,6 +122,7 @@ AccountsViewModel::addSipAccount( std::string& alias,
accountsList_->InsertAt(0, account);
contactListModels_->Insert(account->accountID_, ref new ContactListModel(account->accountID_));
accountAdded(account);
return account;
}
void
......
......@@ -64,7 +64,7 @@ internal:
}
/* functions */
void addRingAccount(std::string& alias,
Account^ addRingAccount(std::string& alias,
std::string& ringID,
std::string& accountID,
std::string& deviceId,
......@@ -75,7 +75,7 @@ internal:
bool dhtPublicInCalls,
bool turnEnabled,
std::string& turnAddress);
void addSipAccount( std::string& alias,
Account^ addSipAccount( std::string& alias,
std::string& accountID,
bool active,
std::string& sipHostname,
......
......@@ -442,7 +442,7 @@ void RingClientUWP::MainPage::OnregistrationStateRegistered(const std::string& a
{
/* do not connect those delegates before initial registration on dht is fine.
Otherwise your going to mess with the wizard */
RingD::instance->nameRegistred += ref new RingClientUWP::NameRegistred(this, &RingClientUWP::MainPage::OnnameRegistred);
RingD::instance->nameRegistered += ref new RingClientUWP::NameRegistered(this, &RingClientUWP::MainPage::OnnameRegistred);
RingD::instance->volatileDetailsChanged += ref new RingClientUWP::VolatileDetailsChanged(this, &MainPage::OnvolatileDetailsChanged);
}
......@@ -450,7 +450,8 @@ void RingClientUWP::MainPage::OncallPlaced(Platform::String ^callId)
{
}
void RingClientUWP::MainPage::OnnameRegistred(bool status)
void
MainPage::OnnameRegistred(bool status, String ^accountId)
{
showLoadingOverlay(false, false);
}
......
......@@ -96,7 +96,7 @@ private:
void OnregistrationStateUnregistered(const std::string& accountId);
void OnregistrationStateRegistered(const std::string& accountId);
void OncallPlaced(Platform::String ^callId);
void OnnameRegistred(bool status);
void OnnameRegistred(bool status, String ^accountId);
void OnvolatileDetailsChanged(const std::string &accountId, const std::map<std::string, std::string>& details);
};
}
......@@ -21,7 +21,6 @@
/* daemon */
#include <dring.h>
#include "dring/call_const.h"
#include "callmanager_interface.h"
#include "configurationmanager_interface.h"
#include "presencemanager_interface.h"
......@@ -121,9 +120,16 @@ RingD::parseAccountDetails(const AccountDetailsBlob& allAccountDetails)
if (account) {
account->name_ = Utils::toPlatformString(alias);
account->_active = active;
account->_upnpState = upnpState;
account->accountType_ = Utils::toPlatformString(type);
account->ringID_ = Utils::toPlatformString(ringID);
account->_autoAnswer = autoAnswer;
account->_turnEnabled = turnEnabled;
account->_turnAddress = Utils::toPlatformString(turnAddress);
account->_deviceId = Utils::toPlatformString(deviceId);
account->_deviceName = Utils::toPlatformString(deviceName);
// load contact requests for the account
auto contactRequests = DRing::getTrustRequests(accountId);
if (auto contactListModel = AccountsViewModel::instance->getContactListModel(std::string(accountId))) {
......@@ -227,281 +233,445 @@ RingD::connectivityChanged()
DRing::connectivityChanged();
}
/* nb: send message during conversation not chat video message */
void RingClientUWP::RingD::sendAccountTextMessage(String^ message)
void
RingD::sendAccountTextMessage(String^ message)
{
/* recipient */
auto item = SmartPanelItemsViewModel::instance->_selectedItem;
tasks_.add_task([this, message]() {
if (auto item = SmartPanelItemsViewModel::instance->_selectedItem) {
auto accountId = AccountListItemsViewModel::instance->_selectedItem->_account->accountID_;
auto contact = item->_contact;
auto toRingId = contact->ringID_;
std::wstring toRingId2(toRingId->Begin());
std::string toRingId3(toRingId2.begin(), toRingId2.end());
auto uri = contact->ringID_;
/* account id */
auto accountId = contact->_accountIdAssociated;
std::wstring accountId2(accountId->Begin());
std::string accountId3(accountId2.begin(), accountId2.end());
auto _accountId = Utils::toString(accountId);
auto _uri = Utils::toString(uri);
/* payload(s) */
IBuffer^ buffUTF8 = CryptographicBuffer::ConvertStringToBinary(message, BinaryStringEncoding::Utf8);
auto stdMessage = Utils::getData(buffUTF8);
std::map<std::string, std::string> payloads;
payloads["text/plain"] = stdMessage;
auto _message = Utils::getData(buffUTF8);
std::map<std::string, std::string> _payload;
_payload["text/plain"] = _message;
/* daemon */
auto sentToken = DRing::sendAccountTextMessage(accountId3, toRingId3, payloads);
auto sentToken = DRing::sendAccountTextMessage(_accountId, _uri, _payload);
/* conversation */
Utils::runOnUIThread([this, sentToken, contact, message]() {
if (sentToken) {
contact->_conversation->addMessage(MSG_FROM_ME, message, std::time(nullptr), false, sentToken.ToString());
/* save contacts conversation to disk */
contact->saveConversationToFile();
} else {
WNG_("message not sent, see daemon outputs");
}
});
}
});
}
// send message during video call
void RingClientUWP::RingD::sendSIPTextMessage(String^ message)
void
RingD::sendSIPTextMessage(String^ message)
{
/* account id */
tasks_.add_task([this, message]() {
if (auto item = SmartPanelItemsViewModel::instance->_selectedItem) {
auto accountId = AccountListItemsViewModel::instance->_selectedItem->_account->accountID_;
std::wstring accountId2(accountId->Begin());
std::string accountId3(accountId2.begin(), accountId2.end());
/* call */
auto item = SmartPanelItemsViewModel::instance->_selectedItem;
auto callId = item->_callId;
std::wstring callId2(callId->Begin());
std::string callId3(callId2.begin(), callId2.end());
/* recipient */
auto contact = item->_contact;
/* payload(s) */
std::wstring message2(message->Begin());
std::string message3(message2.begin(), message2.end());
std::map<std::string, std::string> payloads;
payloads["text/plain"] = message3;
auto task = ref new RingD::Task(Request::SendSIPMessage);
task->_callid_new = callId3;
task->_accountId_new = accountId3;
task->_payload2 = payloads;
auto _accountId = Utils::toString(accountId);
auto _callId = Utils::toString(callId);
auto _message = Utils::toString(message);
std::map<std::string, std::string> _payload;
_payload["text/plain"] = _message;
tasksList_.push(task);
DRing::sendTextMessage(_callId, _payload, _accountId, true /*not used*/);
Utils::runOnUIThread([this, item, message]() {
// No id generated for sip messages within a conversation, so let's generate one
// so we can track message order.
auto contact = item->_contact;
auto messageId = Utils::toPlatformString(Utils::genID(0LL, 9999999999999999999LL));
contact->_conversation->addMessage(MSG_FROM_ME, message, std::time(nullptr), false, messageId);
/* save contacts conversation to disk */
contact->saveConversationToFile();
});
}
});
}
// send vcard
void RingClientUWP::RingD::sendSIPTextMessageVCF(std::string callID, std::map<std::string, std::string> message)
void
RingD::sendSIPTextMessageVCF(std::string callID, std::map<std::string, std::string> message)
{
/* account id */
tasks_.add_task([this, callID, message]() {
auto accountId = AccountListItemsViewModel::instance->_selectedItem->_account->accountID_;
std::wstring accountId2(accountId->Begin());
std::string accountId3(accountId2.begin(), accountId2.end());
auto task = ref new RingD::Task(Request::SendSIPMessage);
task->_callid_new = callID;
task->_accountId_new = accountId3;
task->_payload2 = message;
tasksList_.push(task);
auto _accountId = Utils::toString(accountId);
auto _callId = callID;
DRing::sendTextMessage(_callId, message, _accountId, true /*not used*/);
});
}
void
RingD::createRINGAccount(String^ alias, String^ archivePassword, bool upnp, String^ registeredName)
{
editModeOn_ = true;
tasks_.add_task([this, alias, archivePassword, registeredName]() {
auto _alias = Utils::toString(alias);
auto _password = Utils::toString(archivePassword);
auto _registeredName = Utils::toString(registeredName);
showLoadingOverlay(ResourceMananger::instance->getStringResource("_m_creating_account_"), SuccessColor);
std::map<std::string, std::string> accountDetails;
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::ALIAS, _alias));
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::ARCHIVE_PASSWORD, _password));
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::TYPE, "RING"));
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::UPNP_ENABLED, ring::TRUE_STR));
Utils::runOnUIThread([this, registeredName]() {
showLoadingOverlay(ResourceMananger::instance->getStringResource("_m_creating_account_"), SuccessColor);
isAddingAccount = true;
if (registeredName != "") {
shouldRegister = true;
nameToRegister = registeredName;
}
});
auto task = ref new RingD::Task(Request::AddRingAccount);
task->_alias = alias;
task->_password = archivePassword;
task->_upnp = upnp;
task->_registeredName = registeredName;
tasksList_.push(task);
DRing::addAccount(accountDetails);
});
}
void
RingD::createSIPAccount(String^ alias, String^ sipPassword, String^ sipHostname, String^ sipusername)
{
editModeOn_ = true;
tasks_.add_task([this, alias, sipPassword, sipHostname, sipusername]() {
auto _alias = Utils::toString(alias);
auto _sipPassword = Utils::toString(sipPassword);
auto _sipHostname = Utils::toString(sipHostname);
auto _sipUsername = Utils::toString(sipusername);
showLoadingOverlay(ResourceMananger::instance->getStringResource("_m_creating_account_"), SuccessColor);
std::map<std::string, std::string> accountDetails;
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::ALIAS, _alias));
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::TYPE, "SIP"));
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::PASSWORD, _sipPassword));
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::HOSTNAME, _sipHostname));
accountDetails.insert(std::make_pair(DRing::Account::ConfProperties::USERNAME, _sipUsername));
Utils::runOnUIThread([this]() {
showLoadingOverlay(ResourceMananger::instance->getStringResource("_m_creating_account_"), SuccessColor);
isAddingAccount = true;
});
auto task = ref new RingD::Task(Request::AddSIPAccount);
task->_alias = alias;
task->_sipPassword = sipPassword;
task->_sipHostname = sipHostname;
task->_sipUsername = sipusername;
tasksList_.push(task);
DRing::addAccount(accountDetails);
});
}
void RingClientUWP::RingD::refuseIncommingCall(String^ callId)
void
RingD::refuseIncommingCall(String^ callId)
{
tasksList_.push(ref new RingD::Task(Request::RefuseIncommingCall, callId));
tasks_.add_task([this, callId]() {
auto _callId = Utils::toString(callId);
DRing::refuse(_callId);
});
}
void RingClientUWP::RingD::acceptIncommingCall(String^ callId)
void
RingD::acceptIncommingCall(String^ callId)
{
tasksList_.push(ref new RingD::Task(Request::AcceptIncommingCall, callId));
tasks_.add_task([this, callId]() {
auto _callId = Utils::toString(callId);
DRing::accept(_callId);
});
}
void RingClientUWP::RingD::placeCall(Contact^ contact)
void
RingD::placeCall(Contact^ contact)
{
MSG_("!--->> placeCall");
tasks_.add_task([this, contact]() {
auto _accountId = Utils::toString(contact->_accountIdAssociated);
auto _ringId = Utils::toString(contact->ringID_);
auto _sipUsername = Utils::toString(contact->_name);
if (contact->_accountIdAssociated->IsEmpty()) {
MSG_("adding account id to contact");
contact->_accountIdAssociated = AccountListItemsViewModel::instance->_selectedItem->_account->accountID_;
}
auto task = ref new RingD::Task(Request::PlaceCall);
task->_accountId_new = Utils::toString(contact->_accountIdAssociated);
task->_ringId_new = Utils::toString(contact->ringID_);
task->_sipUsername = contact->_name;
tasksList_.push(task);
auto selectedAccount = AccountListItemsViewModel::instance->_selectedItem->_account;
std::string callId;
if (selectedAccount->accountType_ == "RING")
callId = DRing::placeCall(_accountId, "ring:" + _ringId);
else if (selectedAccount->accountType_ == "SIP")
callId = DRing::placeCall(_accountId, "sip:" + _sipUsername);
// TODO: this UI response should be called at state change?
Utils::runOnUIThread([this, callId, _accountId, _ringId, _sipUsername, selectedAccount]() {
if (auto contactListModel = AccountsViewModel::instance->getContactListModel(std::string(_accountId))) {
Contact^ contact;
if (selectedAccount->accountType_ == "RING")
contact = contactListModel->findContactByRingId(Utils::toPlatformString(_ringId));
else if (selectedAccount->accountType_ == "SIP")
contact = contactListModel->findContactByName(Utils::toPlatformString(_sipUsername));
if (auto item = SmartPanelItemsViewModel::instance->findItem(contact)) {
item->_callId = Utils::toPlatformString(callId);
if (!callId.empty())
callPlaced(Utils::toPlatformString(callId));
}
}
});
});
}
void RingClientUWP::RingD::pauseCall(const std::string & callId)
void
RingD::pauseCall(const std::string & callId)
{
auto task = ref new RingD::Task(Request::PauseCall);
task->_callid_new = callId;
tasksList_.push(task);
tasks_.add_task([this, callId]() {
DRing::hold(callId);
});
}
void RingClientUWP::RingD::unPauseCall(const std::string & callId)
void
RingD::pauseCall(String ^ callId)
{
auto task = ref new RingD::Task(Request::UnPauseCall);
task->_callid_new = callId;
tasksList_.push(task);
tasks_.add_task([this, callId]() {
auto _callId = Utils::toString(callId);
DRing::hold(_callId);
});
}
void RingClientUWP::RingD::raiseWindowResized(float width, float height)
void
RingD::unPauseCall(const std::string & callId)
{
windowResized(width, height);
tasks_.add_task([this, callId]() {
DRing::unhold(callId);
});
}
void
RingD::raiseVCardUpdated(Contact^ contact)
RingD::unPauseCall(String ^ callId)
{
vCardUpdated(contact);
tasks_.add_task([this, callId]() {
auto _callId = Utils::toString(callId);
DRing::unhold(_callId);
});
}
void
RingD::raiseShareRequested()
RingD::hangUpCall2(String ^ callId)
{
shareRequested();
tasks_.add_task([this, callId]() {
auto _callId = Utils::toString(callId);
DRing::hangUp(_callId);
});
}
void RingClientUWP::RingD::cancelOutGoingCall2(String ^ callId)
void
RingD::cancelOutGoingCall2(String ^ callId)
{
MSG_("$1 cancelOutGoingCall2 : " + Utils::toString(callId));
tasksList_.push(ref new RingD::Task(Request::HangUpCall, callId));
hangUpCall2(callId);
}
void
RingD::getKnownDevices(String^ accountId)
{
tasks_.add_task([this, accountId]() {
auto _accountId = Utils::toString(accountId);
auto devicesList = DRing::getKnownRingDevices(_accountId);
if (devicesList.empty())
return;
Utils::runOnUIThread([=]() {
devicesListRefreshed(Utils::convertMap(devicesList));
});
});
}
void RingClientUWP::RingD::hangUpCall2(String ^ callId)
void
RingD::ExportOnRing(String ^ accountId, String ^ password)
{
MSG_("$1 hangUpCall2 : "+Utils::toString(callId));
tasksList_.push(ref new RingD::Task(Request::HangUpCall, callId));
tasks_.add_task([this, accountId, password]() {
auto _accountId = Utils::toString(accountId);
auto _password = Utils::toString(password);
DRing::exportOnRing(_accountId, _password);
});
}
void RingClientUWP::RingD::pauseCall(String ^ callId) // do not use it, rm during refacto
void
RingD::updateAccount(String^ accountId)
{
MSG_("$1 pauseCall : " + Utils::toString(callId));
tasksList_.push(ref new RingD::Task(Request::PauseCall, callId));
tasks_.add_task([this, accountId]() {
auto _accountId = Utils::toString(accountId);
auto account = AccountListItemsViewModel::instance->findItem(accountId)->_account;
std::map<std::string, std::string> accountDetails = DRing::getAccountDetails(_accountId);
std::map<std::string, std::string> accountDetailsOld(accountDetails);
accountDetails[DRing::Account::ConfProperties::ALIAS] = Utils::toString(account->name_);
accountDetails[DRing::Account::ConfProperties::ENABLED] = (account->_active) ? ring::TRUE_STR : ring::FALSE_STR;
accountDetails[DRing::Account::ConfProperties::RING_DEVICE_NAME] = Utils::toString(account->_deviceName);
bool userNameAdded = false;
auto newUsername = Utils::toString(account->_username);
if (accountDetails[DRing::Account::ConfProperties::TYPE] == "RING") {
if (account->_username != "" &&
newUsername.compare(accountDetails[DRing::Account::VolatileProperties::REGISTERED_NAME]) != 0) {
userNameAdded = true;
}
accountDetails[DRing::Account::ConfProperties::UPNP_ENABLED] = (account->_upnpState) ? ring::TRUE_STR : ring::FALSE_STR;
accountDetails[DRing::Account::ConfProperties::AUTOANSWER] = (account->_autoAnswer) ? ring::TRUE_STR : ring::FALSE_STR;
accountDetails[DRing::Account::ConfProperties::DHT::PUBLIC_IN_CALLS] = (account->_dhtPublicInCalls) ? ring::TRUE_STR : ring::FALSE_STR;
accountDetails[DRing::Account::ConfProperties::TURN::ENABLED] = (account->_turnEnabled) ? ring::TRUE_STR : ring::FALSE_STR;
accountDetails[DRing::Account::ConfProperties::TURN::SERVER] = Utils::toString(account->_turnAddress);
}
else {
accountDetails[DRing::Account::ConfProperties::HOSTNAME] = Utils::toString(account->_sipHostname);
accountDetails[DRing::Account::ConfProperties::PASSWORD] = Utils::toString(account->_sipPassword);
accountDetails[DRing::Account::ConfProperties::USERNAME] = Utils::toString(account->_sipUsername);
}
if (accountDetails == accountDetailsOld && !userNameAdded) {
OnaccountUpdated();
return;
}
Utils::runOnUIThread([this]() {
isUpdatingAccount = true;
setOverlayStatusText(ResourceMananger::instance->getStringResource("_m_updating_account_"), SuccessColor);
mainPage->showLoadingOverlay(true, true);
});
DRing::setAccountDetails(_accountId, accountDetails);
if (userNameAdded) {
registerName(account->accountID_, "", account->_username);
}
Configuration::UserPreferences::instance->save();
});
}
void RingClientUWP::RingD::unPauseCall(String ^ callId) // do not use it, rm during refacto
void
RingD::deleteAccount(String ^ accountId)
{
MSG_("$1 unPauseCall : " + Utils::toString(callId));
tasksList_.push(ref new RingD::Task(Request::UnPauseCall, callId));
Utils::runOnUIThread([this]() {
isDeletingAccount = true;
setOverlayStatusText(ResourceMananger::instance->getStringResource("_m_deleting_account_"), "#ffff0000");
mainPage->showLoadingOverlay(true, true);
});
tasks_.add_task([this, accountId]() {
auto _accountId = Utils::toString(accountId);
DRing::removeAccount(_accountId);
});
}
void RingClientUWP::RingD::getKnownDevices(String^ accountId)
void
RingD::registerThisDevice(String ^ pin, String ^ archivePassword)
{
auto task = ref new RingD::Task(Request::GetKnownDevices);
task->_accountId = accountId;
Utils::runOnUIThread([this]() {
showLoadingOverlay(ResourceMananger::instance->getStringResource("_m_creating_account_"), SuccessColor);
isAddingAccount = true;
});
tasks_.add_task([this, pin, archivePassword]() {
auto _pin = Utils::toString(pin);
auto _password = Utils::toString(archivePassword);
std::map<std::string, std::string> deviceDetails;
deviceDetails.insert(std::make_pair(DRing::Account::ConfProperties::TYPE, "RING"));
deviceDetails.insert(std::make_pair(DRing::Account::ConfProperties::ARCHIVE_PIN, _pin));
deviceDetails.insert(std::make_pair(DRing::Account::ConfProperties::ARCHIVE_PASSWORD, _password));
tasksList_.push(task);
DRing::addAccount(deviceDetails);
});
}
void RingClientUWP::RingD::askToExportOnRing(String ^ accountId, String ^ password)
void
RingD::muteVideo(String ^ callId, bool muted)
{
auto task = ref new RingD::Task(Request::ExportOnRing);
task->_accountId = accountId;
task->_password = password;
tasks_.add_task([this, callId, muted]() {
auto _callId = Utils::toString(callId);
DRing::muteLocalMedia(_callId, DRing::Media::Details::MEDIA_TYPE_VIDEO, muted);
});
}
tasksList_.push(task);
void
RingD::muteAudio(const std::string& callId, bool muted)
{
tasks_.add_task([this, callId, muted]() {
auto _callId = callId;
DRing::muteLocalMedia(_callId, DRing::Media::Details::MEDIA_TYPE_AUDIO, muted);
});
}
void RingClientUWP::RingD::eraseCacheFolder()
void
RingD::lookUpName(const std::string& accountId, String^ name)
{
StorageFolder^ localFolder = ApplicationData::Current->LocalFolder;
String^ folderName = ".cache";
tasks_.add_task([this, accountId, name]() {
auto _accountId = accountId;
auto _name = Utils::toString(name);
DRing::lookupName(_accountId,