Commit bf25ecf5 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩
Browse files

Improved real time text characters storage & processing

parent fe2d4da5
......@@ -24,6 +24,8 @@ This changelog file was started on October 2019. Previous changes were more or l
linphone_core_create_publish() now give ownership of the returned LinphoneEvent, which means that it is no longer need to call
linphone_event_ref() after calling these functions. As a consequence, an application not using linphone_event_ref() should now
use linphone_event_unref() when the LinphoneEvent is no longer used, otherwise it will create a memory leak.
- Real time text related function linphone_chat_message_get_char() now will always return the new line character,
which wasn't the case before if the getChar() was done after the composing callback was triggered for this character.
### Fixed
- Internal refactoring of management of locally played tones, in order to fix race conditions.
......
......@@ -296,7 +296,7 @@ LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_core(const LinphoneChatRoom
* @param chat_room #LinphoneChatRoom object @notnil
* @return RFC 4103/T.140 char
*/
LINPHONE_PUBLIC uint32_t linphone_chat_room_get_char(const LinphoneChatRoom *chat_room);
LINPHONE_PUBLIC uint32_t linphone_chat_room_get_char(LinphoneChatRoom *chat_room);
/**
* Returns wether lime is available for given peer or not. *
......
......@@ -106,6 +106,7 @@ namespace Utils {
LINPHONE_PUBLIC std::string stringToLower (const std::string &str);
LINPHONE_PUBLIC char *utf8ToChar (uint32_t ic);
LINPHONE_PUBLIC std::string utf8ToString (const std::vector<uint32_t>& chars);
LINPHONE_PUBLIC inline std::string cStringToCppString (const char *str) {
return str ? str : "";
......
......@@ -201,7 +201,7 @@ void linphone_chat_room_receive_chat_message (LinphoneChatRoom *cr, LinphoneChat
L_GET_PRIVATE_FROM_C_OBJECT(msg)->receive();
}
uint32_t linphone_chat_room_get_char (const LinphoneChatRoom *cr) {
uint32_t linphone_chat_room_get_char (LinphoneChatRoom *cr) {
return L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getChar();
}
......
......@@ -143,7 +143,7 @@ public:
virtual bool canHandleParticipants () const = 0;
virtual std::shared_ptr<Conference> getConference () const = 0;
virtual uint32_t getChar () const = 0;
virtual uint32_t getChar () = 0;
virtual std::shared_ptr<Call> getCall () const = 0;
protected:
......
......@@ -92,11 +92,6 @@ public:
void onIsComposingStateChanged (bool isComposing) override;
void onIsRemoteComposingStateChanged (const Address &remoteAddress, bool isComposing) override;
struct Character {
uint32_t value;
bool hasBeenRead;
};
void realtimeTextReceived (uint32_t character, const std::shared_ptr<Call> &call) override;
void setCallId (const std::string &value) override { callId = value; };
......@@ -126,8 +121,9 @@ private:
bool isEmpty = true;
std::string callId;
std::list<Character> receivedRttCharacters;
std::shared_ptr<ChatMessage> pendingMessage = nullptr;
size_t readCharacterIndex = 0;
std::vector<uint32_t> receivedRttCharacters;
std::vector<uint32_t> lastMessageCharacters;
L_DECLARE_PUBLIC(ChatRoom);
};
......
......@@ -38,6 +38,10 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE
#define NEW_LINE 0x2028
#define CRLF 0x0D0A
#define LF 0x0A
// -----------------------------------------------------------------------------
void ChatRoomPrivate::sendChatMessage (const shared_ptr<ChatMessage> &chatMessage) {
......@@ -45,8 +49,7 @@ void ChatRoomPrivate::sendChatMessage (const shared_ptr<ChatMessage> &chatMessag
shared_ptr<Call> call = q->getCall();
if (call && call->getCurrentParams()->realtimeTextEnabled()) {
uint32_t newLine = 0x2028;
chatMessage->putCharacter(newLine);
chatMessage->putCharacter(NEW_LINE);
} else {
ChatMessagePrivate *dChatMessage = chatMessage->getPrivate();
dChatMessage->setTime(ms_time(0));
......@@ -138,34 +141,27 @@ void ChatRoomPrivate::setIsEmpty (const bool empty) {
void ChatRoomPrivate::realtimeTextReceived (uint32_t character, const shared_ptr<Call> &call) {
L_Q();
const uint32_t new_line = 0x2028;
const uint32_t crlf = 0x0D0A;
const uint32_t lf = 0x0A;
shared_ptr<Core> core = q->getCore();
LinphoneCore *cCore = core->getCCore();
if (call && call->getCurrentParams()->realtimeTextEnabled()) {
if (!pendingMessage) {
pendingMessage = q->createChatMessage();
pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming);
Content *content = new Content();
content->setContentType(ContentType::PlainText);
pendingMessage->addContent(content);
}
Character cmc;
cmc.value = character;
cmc.hasBeenRead = false;
receivedRttCharacters.push_back(cmc);
receivedRttCharacters.push_back(character);
remoteIsComposing.push_back(q->getPeerAddress());
linphone_core_notify_is_composing_received(cCore, getCChatRoom());
if ((character == new_line) || (character == crlf) || (character == lf)) {
if ((character == NEW_LINE) || (character == CRLF) || (character == LF)) {
// End of message
auto content = pendingMessage->getContents().front();
lDebug() << "New line received, forge a message with content " << content->getBodyAsString();
string completeText = Utils::utf8ToString(lastMessageCharacters);
shared_ptr<ChatMessage> pendingMessage = q->createChatMessage();
pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming);
Content *content = new Content();
content->setContentType(ContentType::PlainText);
content->setBodyFromUtf8(completeText);
pendingMessage->addContent(content);
bctbx_debug("New line received, forge a message with content [%s]", content->getBodyAsString().c_str());
pendingMessage->getPrivate()->setState(ChatMessage::State::Delivered);
pendingMessage->getPrivate()->setTime(::ms_time(0));
......@@ -174,14 +170,11 @@ void ChatRoomPrivate::realtimeTextReceived (uint32_t character, const shared_ptr
}
onChatMessageReceived(pendingMessage);
pendingMessage = nullptr;
receivedRttCharacters.clear();
lastMessageCharacters.clear();
} else {
char *value = Utils::utf8ToChar(character);
auto content = pendingMessage->getContents().front();
content->setBodyFromUtf8(content->getBodyAsUtf8String() + string(value));
lDebug() << "Received RTT character: " << value << " (" << character << "), pending text is " << content->getBodyAsUtf8String();
delete[] value;
lastMessageCharacters.push_back(character);
string completeText = Utils::utf8ToString(lastMessageCharacters);
bctbx_debug("Received RTT character: [%llu], pending text is [%s]", character, completeText.c_str());
}
}
}
......@@ -743,16 +736,21 @@ bool ChatRoom::addParticipants (const std::list<IdentityAddress> &addresses) {
return soFarSoGood;
}
uint32_t ChatRoom::getChar () const {
uint32_t ChatRoom::getChar () {
L_D();
for (const auto &cmc : d->receivedRttCharacters) {
if (!cmc.hasBeenRead) {
const_cast<ChatRoomPrivate::Character *>(&cmc)->hasBeenRead = true;
return cmc.value;
}
uint32_t character = 0;
if (d->readCharacterIndex < d->receivedRttCharacters.size()) {
character = d->receivedRttCharacters.at(d->readCharacterIndex);
d->readCharacterIndex += 1;
}
return 0;
if (d->readCharacterIndex == d->receivedRttCharacters.size()) {
d->readCharacterIndex = 0;
d->receivedRttCharacters.clear();
}
return character;
}
std::shared_ptr<Call> ChatRoom::getCall () const {
......
......@@ -107,7 +107,7 @@ public:
return (getConference() != nullptr);
}
uint32_t getChar () const override;
uint32_t getChar () override;
std::shared_ptr<Call> getCall () const override;
protected:
......
......@@ -397,8 +397,7 @@ bool ProxyChatRoom::canHandleParticipants () const {
return d->chatRoom->canHandleParticipants();
}
uint32_t ProxyChatRoom::getChar () const {
uint32_t ProxyChatRoom::getChar () {
L_D();
return d->chatRoom->getChar();
}
......@@ -408,5 +407,4 @@ std::shared_ptr<Call> ProxyChatRoom::getCall () const {
return d->chatRoom->getCall();
}
LINPHONE_END_NAMESPACE
......@@ -131,7 +131,7 @@ public:
void setState (ConferenceInterface::State state) override;
uint32_t getChar () const override;
uint32_t getChar () override;
std::shared_ptr<Call> getCall () const override;
protected:
......
......@@ -179,6 +179,14 @@ char *Utils::utf8ToChar (uint32_t ic) {
return result;
}
std::string Utils::utf8ToString (const std::vector<uint32_t>& chars) {
std::ostringstream ss;
for (auto character : chars) {
ss << Utils::utf8ToChar(character);
}
return ss.str();
}
string Utils::trim (const string &str) {
auto itFront = find_if_not(str.begin(), str.end(), [] (int c) { return isspace(c); });
auto itBack = find_if_not(str.rbegin(), str.rend(), [] (int c) { return isspace(c); }).base();
......
......@@ -2643,6 +2643,12 @@ static void real_time_text_conversation(void) {
linphone_chat_message_send(pauline_rtt_message);
linphone_chat_message_send(marie_rtt_message);
// Read new line character
BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, strlen(message1_1) + 1, 5000));
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), (char)0x2028, char, "%c");
BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, strlen(message1_2) + 1, 5000));
BC_ASSERT_EQUAL(linphone_chat_room_get_char(pauline_chat_room), (char)0x2028, char, "%c");
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1));
{
LinphoneChatMessage * msg = marie->stat.last_received_chat_message;
......@@ -2681,6 +2687,12 @@ static void real_time_text_conversation(void) {
linphone_chat_message_send(pauline_rtt_message);
linphone_chat_message_send(marie_rtt_message);
// Read new line character
BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, strlen(message2_1) + 1, 5000));
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), (char)0x2028, char, "%c");
BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, strlen(message2_2) + 1, 5000));
BC_ASSERT_EQUAL(linphone_chat_room_get_char(pauline_chat_room), (char)0x2028, char, "%c");
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1));
{
LinphoneChatMessage * msg = marie->stat.last_received_chat_message;
......@@ -2900,6 +2912,9 @@ static void real_time_text_and_early_media(void) {
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
linphone_call_params_unref(pauline_params);
chars_received = marie->stat.number_of_LinphoneIsComposingActiveReceived;
// Read new line character
BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), (char)0x2028, char, "%c");
/* Send RTT again once the call is established. */
rtt_message = linphone_chat_room_create_message_from_utf8(pauline_chat_room,NULL);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment