Commit 7c4533b8 authored by Ghislain MARY's avatar Ghislain MARY

Restore the ability for a user to define if a ChatMessage is to be stored or not.

parent b39e220d
......@@ -167,6 +167,21 @@ LINPHONE_PUBLIC const char * linphone_chat_message_get_file_transfer_filepath(Li
// =============================================================================
/**
* Get if a chat message is to be stored.
* @param[in] message LinphoneChatMessage object
* @return Whether or not the message is to be stored
*/
LINPHONE_PUBLIC bool_t linphone_chat_message_get_to_be_stored(const LinphoneChatMessage *message);
/**
* Set if a chat message is to be stored.
* This content type must match a content that is text representable, such as text/plain, text/html or image/svg+xml.
* @param[in] message LinphoneChatMessage object
* @param[in] to_be_stored Whether or not the chat message is to be stored
*/
LINPHONE_PUBLIC void linphone_chat_message_set_to_be_stored(LinphoneChatMessage *message, bool_t to_be_stored);
LINPHONE_PUBLIC unsigned int linphone_chat_message_store(LinphoneChatMessage *msg);
/**
......
......@@ -177,6 +177,14 @@ const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChat
return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getErrorInfo();
}
bool_t linphone_chat_message_get_to_be_stored(const LinphoneChatMessage *message) {
return L_GET_CPP_PTR_FROM_C_OBJECT(message)->getToBeStored();
}
void linphone_chat_message_set_to_be_stored(LinphoneChatMessage *message, bool_t to_be_stored) {
L_GET_CPP_PTR_FROM_C_OBJECT(message)->setToBeStored(!!to_be_stored);
}
// =============================================================================
// Methods
// =============================================================================
......
......@@ -59,11 +59,11 @@ public:
void setDirection (ChatMessage::Direction dir);
void setState(ChatMessage::State state, bool force = false, bool storeInDb = true);
void setState (ChatMessage::State state, bool force = false);
void setTime(time_t time);
void setTime (time_t time);
void setIsReadOnly(bool readOnly);
void setIsReadOnly (bool readOnly);
void setImdnMessageId (const std::string &imdnMessageId);
......@@ -75,20 +75,20 @@ public:
this->toAddress = toAddress;
}
belle_http_request_t *getHttpRequest() const;
void setHttpRequest(belle_http_request_t *request);
belle_http_request_t *getHttpRequest () const;
void setHttpRequest (belle_http_request_t *request);
SalOp *getSalOp() const;
void setSalOp(SalOp *op);
SalOp *getSalOp () const;
void setSalOp (SalOp *op);
SalCustomHeader *getSalCustomHeaders() const;
void setSalCustomHeaders(SalCustomHeader *headers);
SalCustomHeader *getSalCustomHeaders () const;
void setSalCustomHeaders (SalCustomHeader *headers);
void addSalCustomHeader(const std::string& name, const std::string& value);
void removeSalCustomHeader(const std::string& name);
std::string getSalCustomHeaderValue(const std::string& name);
void addSalCustomHeader (const std::string& name, const std::string& value);
void removeSalCustomHeader (const std::string& name);
std::string getSalCustomHeaderValue (const std::string& name);
void loadFileTransferUrlFromBodyToContent();
void loadFileTransferUrlFromBodyToContent ();
void setChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
......@@ -96,11 +96,11 @@ public:
// Deprecated methods only used for C wrapper, to be removed some day...
// -----------------------------------------------------------------------------
const ContentType &getContentType();
void setContentType(const ContentType &contentType);
const ContentType &getContentType ();
void setContentType (const ContentType &contentType);
const std::string &getText();
void setText(const std::string &text);
const std::string &getText ();
void setText (const std::string &text);
const std::string &getFileTransferFilepath () const;
void setFileTransferFilepath (const std::string &path);
......@@ -110,23 +110,25 @@ public:
const std::string &getExternalBodyUrl () const;
bool hasTextContent() const;
const Content* getTextContent() const;
bool hasTextContent () const;
const Content* getTextContent () const;
bool hasFileTransferContent() const;
const Content* getFileTransferContent() const;
bool hasFileTransferContent () const;
const Content* getFileTransferContent () const;
LinphoneContent *getFileTransferInformation() const;
void setFileTransferInformation(const LinphoneContent *content);
LinphoneContent *getFileTransferInformation () const;
void setFileTransferInformation (const LinphoneContent *content);
bool downloadFile ();
void sendImdn(Imdn::Type imdnType, LinphoneReason reason);
void sendImdn (Imdn::Type imdnType, LinphoneReason reason);
LinphoneReason receive();
void send();
void notifyReceiving ();
LinphoneReason receive ();
void send ();
void store();
void storeInDb ();
void updateInDb ();
private:
// TODO: Clean attributes.
......@@ -166,6 +168,8 @@ private:
ChatMessage::State state = ChatMessage::State::Idle;
ChatMessage::Direction direction = ChatMessage::Direction::Incoming;
bool toBeStored = true;
L_DECLARE_PUBLIC(ChatMessage);
};
......
......@@ -63,7 +63,7 @@ void ChatMessagePrivate::setIsReadOnly (bool readOnly) {
isReadOnly = readOnly;
}
void ChatMessagePrivate::setState (ChatMessage::State s, bool force, bool storeInDb) {
void ChatMessagePrivate::setState (ChatMessage::State s, bool force) {
L_Q();
if (force)
......@@ -98,9 +98,7 @@ void ChatMessagePrivate::setState (ChatMessage::State s, bool force, bool storeI
if (cbs && linphone_chat_message_cbs_get_msg_state_changed(cbs))
linphone_chat_message_cbs_get_msg_state_changed(cbs)(msg, linphone_chat_message_get_state(msg));
if (storeInDb) {
store();
}
updateInDb();
}
belle_http_request_t *ChatMessagePrivate::getHttpRequest () const {
......@@ -205,7 +203,7 @@ void ChatMessagePrivate::setAppdata (const string &data) {
break;
}
}
store();
updateInDb();
}
const string &ChatMessagePrivate::getExternalBodyUrl () const {
......@@ -381,6 +379,29 @@ static void forceUtf8Content (Content &content) {
L_END_LOG_EXCEPTION
}
void ChatMessagePrivate::notifyReceiving () {
L_Q();
if ((getContentType() == ContentType::Imdn) || (getContentType() == ContentType::ImIsComposing))
return;
LinphoneChatRoom *chatRoom = L_GET_C_BACK_PTR(q->getChatRoom());
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chatRoom);
LinphoneChatRoomCbsParticipantAddedCb cb = linphone_chat_room_cbs_get_chat_message_received(cbs);
shared_ptr<ConferenceChatMessageEvent> event = make_shared<ConferenceChatMessageEvent>(
::time(nullptr), q->getSharedFromThis()
);
if (cb)
cb(chatRoom, L_GET_C_BACK_PTR(event));
// Legacy
q->getChatRoom()->getPrivate()->notifyChatMessageReceived(q->getSharedFromThis());
if (toBeStored)
storeInDb();
q->sendDeliveryNotification(LinphoneReasonNone);
}
LinphoneReason ChatMessagePrivate::receive () {
L_Q();
int errorCode = 0;
......@@ -389,8 +410,6 @@ LinphoneReason ChatMessagePrivate::receive () {
shared_ptr<Core> core = q->getCore();
shared_ptr<AbstractChatRoom> chatRoom = q->getChatRoom();
setState(ChatMessage::State::Delivered, false, false); // Wait for decryption and CPIM to reveal the real message to know if it must be stored or not
// ---------------------------------------
// Start of message modification
// ---------------------------------------
......@@ -451,6 +470,8 @@ LinphoneReason ChatMessagePrivate::receive () {
// End of message modification
// ---------------------------------------
setState(ChatMessage::State::Delivered, false);
if (errorCode <= 0) {
bool foundSupportContentType = false;
for (Content *c : contents) {
......@@ -482,7 +503,8 @@ LinphoneReason ChatMessagePrivate::receive () {
return reason;
}
store();
if ((getContentType() == ContentType::ImIsComposing) || (getContentType() == ContentType::Imdn))
toBeStored = false;
return reason;
}
......@@ -493,6 +515,8 @@ void ChatMessagePrivate::send () {
LinphoneCall *lcall = nullptr;
int errorCode = 0;
storeInDb();
if ((currentSendStep & ChatMessagePrivate::Step::FileUpload) == ChatMessagePrivate::Step::FileUpload) {
lInfo() << "File upload step already done, skipping";
} else {
......@@ -634,8 +658,6 @@ void ChatMessagePrivate::send () {
if (imdnId.empty())
setImdnMessageId(op->get_call_id()); /* must be known at that time */
//store(); // Store will be done right below in the setState(InProgress)
if (lcall && linphone_call_get_op(lcall) == op) {
/* In this case, chat delivery status is not notified, so unrefing chat message right now */
/* Might be better fixed by delivering status, but too costly for now */
......@@ -649,43 +671,17 @@ void ChatMessagePrivate::send () {
}
}
void ChatMessagePrivate::store() {
void ChatMessagePrivate::storeInDb () {
L_Q();
// TODO: store message in the future
if (linphone_core_conference_server_enabled(q->getCore()->getCCore())) return;
bool messageToBeStored = true;
for (Content *c : contents) {
ContentType contentType = c->getContentType();
if (contentType == ContentType::Imdn || contentType == ContentType::ImIsComposing) {
messageToBeStored = false;
break;
}
}
if (!messageToBeStored) {
return;
}
unique_ptr<MainDb> &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb;
if (dbKey.isValid()) {
shared_ptr<EventLog> eventLog = mainDb->getEventFromKey(dbKey);
mainDb->updateEvent(eventLog);
if (direction == ChatMessage::Direction::Incoming) {
if (!hasFileTransferContent()) {
// Incoming message doesn't have any download waiting anymore, we can remove it's event from the transients
q->getChatRoom()->getPrivate()->removeTransientEvent(eventLog);
}
} else {
if (state == ChatMessage::State::Delivered || state == ChatMessage::State::NotDelivered) {
// Once message has reached this state it won't change anymore so we can remove the event from the transients
q->getChatRoom()->getPrivate()->removeTransientEvent(eventLog);
}
}
updateInDb();
} else {
shared_ptr<EventLog> eventLog = make_shared<ConferenceChatMessageEvent>(time, q->getSharedFromThis());
mainDb->addEvent(eventLog);
q->getChatRoom()->getCore()->getPrivate()->mainDb->addEvent(eventLog);
if (direction == ChatMessage::Direction::Incoming) {
if (hasFileTransferContent()) {
......@@ -699,6 +695,29 @@ void ChatMessagePrivate::store() {
}
}
void ChatMessagePrivate::updateInDb () {
L_Q();
if (!dbKey.isValid())
return;
unique_ptr<MainDb> &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb;
shared_ptr<EventLog> eventLog = mainDb->getEventFromKey(dbKey);
mainDb->updateEvent(eventLog);
if (direction == ChatMessage::Direction::Incoming) {
if (!hasFileTransferContent()) {
// Incoming message doesn't have any download waiting anymore, we can remove it's event from the transients
q->getChatRoom()->getPrivate()->removeTransientEvent(eventLog);
}
} else {
if (state == ChatMessage::State::Delivered || state == ChatMessage::State::NotDelivered) {
// Once message has reached this state it won't change anymore so we can remove the event from the transients
q->getChatRoom()->getPrivate()->removeTransientEvent(eventLog);
}
}
}
// -----------------------------------------------------------------------------
ChatMessage::ChatMessage (const shared_ptr<AbstractChatRoom> &chatRoom, ChatMessage::Direction direction) :
......@@ -799,6 +818,16 @@ const IdentityAddress &ChatMessage::getToAddress () const {
return d->toAddress;
}
bool ChatMessage::getToBeStored () const {
L_D();
return d->toBeStored;
}
void ChatMessage::setToBeStored (bool value) {
L_D();
d->toBeStored = value;
}
// -----------------------------------------------------------------------------
const LinphoneErrorInfo *ChatMessage::getErrorInfo () const {
......
......@@ -90,6 +90,9 @@ public:
bool isRead () const;
bool isReadOnly () const;
bool getToBeStored () const;
void setToBeStored (bool value);
const std::list<Content *> &getContents () const;
void addContent (Content &content);
void removeContent (const Content &content);
......
......@@ -45,6 +45,7 @@ public:
virtual void addTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
virtual void removeTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
virtual void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
virtual void notifyUndecryptableChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
virtual LinphoneReason onSipMessageReceived (SalOp *op, const SalMessage *message) = 0;
......
......@@ -52,7 +52,7 @@ public:
std::shared_ptr<ChatMessage> createChatMessage (ChatMessage::Direction direction);
std::list<std::shared_ptr<ChatMessage>> findChatMessages (const std::string &messageId) const;
void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage);
void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override;
void notifyIsComposingReceived (const Address &remoteAddress, bool isComposing);
void notifyStateChanged ();
void notifyUndecryptableChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override;
......
......@@ -244,24 +244,10 @@ end:
}
void ChatRoomPrivate::onChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) {
L_Q();
ContentType contentType = chatMessage->getPrivate()->getContentType();
if (contentType != ContentType::Imdn && contentType != ContentType::ImIsComposing) {
LinphoneChatRoom *chatRoom = L_GET_C_BACK_PTR(q);
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chatRoom);
LinphoneChatRoomCbsParticipantAddedCb cb = linphone_chat_room_cbs_get_chat_message_received(cbs);
shared_ptr<ConferenceChatMessageEvent> event = make_shared<ConferenceChatMessageEvent>(time(nullptr), chatMessage);
if (cb)
cb(chatRoom, L_GET_C_BACK_PTR(event));
// Legacy
notifyChatMessageReceived(chatMessage);
const IdentityAddress &fromAddress = chatMessage->getFromAddress();
isComposingHandler->stopRemoteRefreshTimer(fromAddress.asString());
notifyIsComposingReceived(fromAddress, false);
chatMessage->sendDeliveryNotification(LinphoneReasonNone);
}
const IdentityAddress &fromAddress = chatMessage->getFromAddress();
isComposingHandler->stopRemoteRefreshTimer(fromAddress.asString());
notifyIsComposingReceived(fromAddress, false);
chatMessage->getPrivate()->notifyReceiving();
}
void ChatRoomPrivate::onImdnReceived (const string &text) {
......
......@@ -52,6 +52,10 @@ public:
chatRoom->getPrivate()->removeTransientEvent(eventLog);
}
inline void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override {
chatRoom->getPrivate()->notifyChatMessageReceived(chatMessage);
}
inline void notifyUndecryptableChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override {
chatRoom->getPrivate()->notifyUndecryptableChatMessageReceived(chatMessage);
}
......
......@@ -70,7 +70,7 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, Linp
pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming);
if (lp_config_get_int(linphone_core_get_config(cCore), "misc", "store_rtt_messages", 1) == 1)
pendingMessage->getPrivate()->store();
pendingMessage->getPrivate()->storeInDb();
onChatMessageReceived(pendingMessage);
pendingMessage = nullptr;
......
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