Commit 18696f2a authored by Simon Morlat's avatar Simon Morlat

Fix background task usage when receiving a REFER to join a chatroom.

Add a timeout, because on Android wake locks have no limit in time. The timeout will secure that whatever happens, the wake lock is always released after a reasonable time.
parent b9eaf0a7
...@@ -198,7 +198,8 @@ void CallPrivate::onAckReceived (const shared_ptr<CallSession> &session, Linphon ...@@ -198,7 +198,8 @@ void CallPrivate::onAckReceived (const shared_ptr<CallSession> &session, Linphon
} }
void CallPrivate::onBackgroundTaskToBeStarted (const shared_ptr<CallSession> &session) { void CallPrivate::onBackgroundTaskToBeStarted (const shared_ptr<CallSession> &session) {
bgTask.start(); L_Q();
bgTask.start(q->getCore(),30);
} }
void CallPrivate::onBackgroundTaskToBeStopped (const shared_ptr<CallSession> &session) { void CallPrivate::onBackgroundTaskToBeStopped (const shared_ptr<CallSession> &session) {
......
...@@ -53,7 +53,6 @@ private: ...@@ -53,7 +53,6 @@ private:
ClientGroupChatRoom::CapabilitiesMask capabilities = ClientGroupChatRoom::Capabilities::Conference; ClientGroupChatRoom::CapabilitiesMask capabilities = ClientGroupChatRoom::Capabilities::Conference;
bool deletionOnTerminationEnabled = false; bool deletionOnTerminationEnabled = false;
BackgroundTask bgTask; BackgroundTask bgTask;
L_DECLARE_PUBLIC(ClientGroupChatRoom); L_DECLARE_PUBLIC(ClientGroupChatRoom);
}; };
......
...@@ -139,8 +139,10 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged ( ...@@ -139,8 +139,10 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged (
if (q->getState() == ChatRoom::State::CreationPending) { if (q->getState() == ChatRoom::State::CreationPending) {
IdentityAddress addr(session->getRemoteContactAddress()->asStringUriOnly()); IdentityAddress addr(session->getRemoteContactAddress()->asStringUriOnly());
q->onConferenceCreated(addr); q->onConferenceCreated(addr);
if (session->getRemoteContactAddress()->hasParam("isfocus")) if (session->getRemoteContactAddress()->hasParam("isfocus")){
bgTask.start(q->getCore(), 32); /*it will be stopped when receiving the first notify*/
qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId()); qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId());
}
} else if (q->getState() == ChatRoom::State::TerminationPending) } else if (q->getState() == ChatRoom::State::TerminationPending)
qConference->getPrivate()->focus->getPrivate()->getSession()->terminate(); qConference->getPrivate()->focus->getPrivate()->getSession()->terminate();
} else if (newState == CallSession::State::Released) { } else if (newState == CallSession::State::Released) {
...@@ -179,15 +181,14 @@ ClientGroupChatRoom::ClientGroupChatRoom ( ...@@ -179,15 +181,14 @@ ClientGroupChatRoom::ClientGroupChatRoom (
const string &subject const string &subject
) : ChatRoom(*new ClientGroupChatRoomPrivate, core, ChatRoomId(IdentityAddress(), me)), ) : ChatRoom(*new ClientGroupChatRoomPrivate, core, ChatRoomId(IdentityAddress(), me)),
RemoteConference(core, me, nullptr) { RemoteConference(core, me, nullptr) {
L_D();
L_D_T(RemoteConference, dConference); L_D_T(RemoteConference, dConference);
L_D();
d->bgTask.setName("Client group chat room refer received");
IdentityAddress focusAddr(uri); IdentityAddress focusAddr(uri);
dConference->focus = make_shared<Participant>(focusAddr); dConference->focus = make_shared<Participant>(focusAddr);
dConference->focus->getPrivate()->addDevice(focusAddr); dConference->focus->getPrivate()->addDevice(focusAddr);
RemoteConference::setSubject(subject); RemoteConference::setSubject(subject);
d->bgTask.setName("Subscribe/notify of full state conference");
} }
ClientGroupChatRoom::ClientGroupChatRoom ( ClientGroupChatRoom::ClientGroupChatRoom (
...@@ -410,7 +411,6 @@ void ClientGroupChatRoom::join () { ...@@ -410,7 +411,6 @@ void ClientGroupChatRoom::join () {
shared_ptr<CallSession> session = dConference->focus->getPrivate()->getSession(); shared_ptr<CallSession> session = dConference->focus->getPrivate()->getSession();
if (!session && ((getState() == ChatRoom::State::Instantiated) || (getState() == ChatRoom::State::Terminated))) { if (!session && ((getState() == ChatRoom::State::Instantiated) || (getState() == ChatRoom::State::Terminated))) {
d->bgTask.start();
session = d->createSession(); session = d->createSession();
} }
if (session) { if (session) {
...@@ -424,7 +424,6 @@ void ClientGroupChatRoom::leave () { ...@@ -424,7 +424,6 @@ void ClientGroupChatRoom::leave () {
L_D(); L_D();
L_D_T(RemoteConference, dConference); L_D_T(RemoteConference, dConference);
d->bgTask.start();
dConference->eventHandler->unsubscribe(); dConference->eventHandler->unsubscribe();
shared_ptr<CallSession> session = dConference->focus->getPrivate()->getSession(); shared_ptr<CallSession> session = dConference->focus->getPrivate()->getSession();
...@@ -475,18 +474,19 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) { ...@@ -475,18 +474,19 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) {
void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) { void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {
L_D(); L_D();
d->setState(ChatRoom::State::Created); d->setState(ChatRoom::State::Created);
if (getParticipantCount() == 1) { if (getParticipantCount() == 1) {
ChatRoomId id(getParticipants().front()->getAddress(), getMe()->getAddress()); ChatRoomId id(getParticipants().front()->getAddress(), getMe()->getAddress());
shared_ptr<AbstractChatRoom> chatRoom = getCore()->findChatRoom(id); shared_ptr<AbstractChatRoom> chatRoom = getCore()->findChatRoom(id);
if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) { if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) {
BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom); BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom);
return; goto end;
} }
} }
d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis()); d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis());
end:
d->bgTask.stop();
// TODO: Bug. Event is inserted many times. // TODO: Bug. Event is inserted many times.
// Avoid this in the future. Deal with signals/slots system. // Avoid this in the future. Deal with signals/slots system.
#if 0 #if 0
...@@ -496,7 +496,6 @@ void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) { ...@@ -496,7 +496,6 @@ void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {
d->chatRoomId d->chatRoomId
)); ));
#endif #endif
d->bgTask.stop();
} }
void ClientGroupChatRoom::onParticipantAdded (const shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) { void ClientGroupChatRoom::onParticipantAdded (const shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) {
......
...@@ -485,7 +485,10 @@ error: ...@@ -485,7 +485,10 @@ error:
} }
void FileTransferChatMessageModifier::fileUploadBeginBackgroundTask () { void FileTransferChatMessageModifier::fileUploadBeginBackgroundTask () {
bgTask.start(); shared_ptr<ChatMessage> message = chatMessage.lock();
if (!message)
return;
bgTask.start(message->getCore());
} }
void FileTransferChatMessageModifier::fileUploadEndBackgroundTask () { void FileTransferChatMessageModifier::fileUploadEndBackgroundTask () {
......
...@@ -20,25 +20,41 @@ ...@@ -20,25 +20,41 @@
#include "background-task.h" #include "background-task.h"
#include "c-wrapper/internal/c-sal.h" #include "c-wrapper/internal/c-sal.h"
#include "logger/logger.h" #include "logger/logger.h"
#include "core/core-p.h"
#include "private.h" //to get access to the Sal
// ============================================================================= // =============================================================================
LINPHONE_BEGIN_NAMESPACE LINPHONE_BEGIN_NAMESPACE
static void notifier (void *context) { void BackgroundTask::sHandleTimeout(void *context) {
static_cast<BackgroundTask *>(context)->handleTimeout(); static_cast<BackgroundTask *>(context)->handleTimeout();
} }
void BackgroundTask::start () { int BackgroundTask::sHandleSalTimeout(void *data, unsigned int events){
static_cast<BackgroundTask *>(data)->handleSalTimeout();
return BELLE_SIP_STOP;
}
void BackgroundTask::handleSalTimeout(){
lWarning() << "Background task [" << mId << "] with name : [" << mName << "] is now expiring.";
stop();
}
void BackgroundTask::start (const std::shared_ptr<Core> &core, int max_duration_seconds) {
if (mName.empty()) { if (mName.empty()) {
lError() << "No name was set on background task."; lError() << "No name was set on background task.";
return; return;
} }
unsigned long newId = sal_begin_background_task(mName.c_str(), notifier, this); unsigned long newId = sal_begin_background_task(mName.c_str(), sHandleTimeout, this);
lInfo() << "Starting background task [" << newId << "] with name : [" << mName << "]."; lInfo() << "Starting background task [" << newId << "] with name : [" << mName << "] and expiration of ["<<max_duration_seconds<<"].";
stop(); stop();
mId = newId; mId = newId;
if (max_duration_seconds > 0){
mSal = core->getCCore()->sal;
mTimeout = mSal->create_timer(sHandleSalTimeout, this, (unsigned int) max_duration_seconds * 1000, mName.c_str());
}
} }
void BackgroundTask::stop () { void BackgroundTask::stop () {
...@@ -47,11 +63,16 @@ void BackgroundTask::stop () { ...@@ -47,11 +63,16 @@ void BackgroundTask::stop () {
lInfo() << "Ending background task [" << mId << "] with name : [" << mName << "]."; lInfo() << "Ending background task [" << mId << "] with name : [" << mName << "].";
sal_end_background_task(mId); sal_end_background_task(mId);
if (mTimeout){
mSal->cancel_timer(mTimeout);
belle_sip_object_unref(mTimeout);
mTimeout = NULL;
}
mId = 0; mId = 0;
} }
void BackgroundTask::handleTimeout () { void BackgroundTask::handleTimeout () {
lWarning() << "Background task [" << mId << "] with name : [" << mName << "] has expired before completion..."; lWarning() << "Background task [" << mId << "] with name : [" << mName << "] is expiring from OS before completion...";
stop(); stop();
} }
......
...@@ -23,15 +23,19 @@ ...@@ -23,15 +23,19 @@
#include <string> #include <string>
#include "linphone/utils/general.h" #include "linphone/utils/general.h"
#include "sal/sal.h"
// ============================================================================= // =============================================================================
LINPHONE_BEGIN_NAMESPACE LINPHONE_BEGIN_NAMESPACE
class Sal;
class Core;
class BackgroundTask { class BackgroundTask {
public: public:
BackgroundTask () = default; BackgroundTask() : mTimeout(NULL), mSal(NULL), mId(0){}
BackgroundTask (const std::string &name) : mName(name) {} BackgroundTask (const std::string &name) : mTimeout(NULL), mSal(NULL), mName(name), mId(0) {}
virtual ~BackgroundTask () { virtual ~BackgroundTask () {
stop(); stop();
} }
...@@ -39,19 +43,26 @@ public: ...@@ -39,19 +43,26 @@ public:
void setName (const std::string &name) { void setName (const std::string &name) {
mName = name; mName = name;
} }
/**
void start (); * Start a long running task for at most max_duration_seconds, after which it is automatically terminated
void stop (); */
void start(const std::shared_ptr<Core> &core, int max_duration_seconds = 15*60); /*15 mn by default, like on iOS*/
void stop();
const std::string &getName () const { const std::string &getName () const {
return mName; return mName;
} }
protected:
virtual void handleTimeout (); virtual void handleTimeout ();
private: private:
static int sHandleSalTimeout(void *data, unsigned int events);
static void sHandleTimeout(void *data);
belle_sip_source_t *mTimeout;
Sal *mSal;
std::string mName; std::string mName;
unsigned long mId = 0; unsigned long mId = 0;
void handleSalTimeout();
}; };
LINPHONE_END_NAMESPACE LINPHONE_END_NAMESPACE
......
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