1 /*
2 * Copyright 2014 Canonical Ltd.
3 * Authors:
4 * Roberto Mier
5 * Tiago Herrmann
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21 #include "sessionmanager.h"
22
23 Q_LOGGING_CATEGORY(TG_CORE_SESSIONMANAGER, "tg.core.sessionmanager")
24
SessionManager(Session * session,Settings * settings,CryptoUtils * crypto,QObject * parent)25 SessionManager::SessionManager(Session *session, Settings *settings, CryptoUtils *crypto, QObject *parent) :
26 QObject(parent),
27 mSettings(settings),
28 mCrypto(crypto),
29 mMainSession(session)
30 {
31 connect(mMainSession, SIGNAL(sessionReady(DC*)), this, SIGNAL(mainSessionReady()), Qt::UniqueConnection);
32 connect(mMainSession, SIGNAL(sessionClosed(qint64)), this, SIGNAL(mainSessionClosed()), Qt::UniqueConnection);
33 }
34
~SessionManager()35 SessionManager::~SessionManager() {
36 if (mMainSession) {
37 mMainSession->close();
38 }
39 Q_FOREACH (Session *session, mFileSessions) {
40 if (session) {
41 session->close();
42 }
43 }
44 }
45
fileSession(DC * dc)46 Session *SessionManager::fileSession(DC *dc) {
47 Session *session;
48 qint32 &resourcesAtDc = mDcResourceCounts[dc->id()];
49
50 if (!resourcesAtDc) {
51 session = createFileSession(dc);
52 } else {
53 qint64 sessionId = mDcSessionIds.value(dc->id());
54 session = mFileSessions.value(sessionId);
55 }
56
57 resourcesAtDc++;
58 qCDebug(TG_CORE_SESSIONMANAGER) << "file session resources at DC" << dc->id() << resourcesAtDc;
59
60 return session;
61 }
62
createFileSession(DC * dc)63 Session *SessionManager::createFileSession(DC *dc) {
64 Session *session = createSession(dc);
65 mFileSessions.insert(session->sessionId(), session);
66 mDcSessionIds.insert(dc->id(), session->sessionId());
67 qCDebug(TG_CORE_SESSIONMANAGER) << "created file session at DC" << dc->id();
68 return session;
69 }
70
createSession(DC * dc)71 Session *SessionManager::createSession(DC *dc) {
72 Session *session = new Session(dc, mSettings, mCrypto, this);
73 connect(session, SIGNAL(sessionReleased(qint64)), SLOT(onSessionReleased(qint64)));
74 connect(session, SIGNAL(sessionClosed(qint64)), SLOT(onSessionClosed(qint64)));
75 connectResponsesSignals(session);
76 return session;
77 }
78
onSessionReleased(qint64 sessionId)79 void SessionManager::onSessionReleased(qint64 sessionId) {
80 Session *session = mFileSessions.value(sessionId, 0);
81 if (session) {
82 qint32 dcId = session->dc()->id();
83 qint32 &resourcesAtDc = mDcResourceCounts[dcId];
84 resourcesAtDc--;
85
86 if (!resourcesAtDc) {
87 session->close();
88 mDcSessionIds.remove(dcId);
89 qCDebug(TG_CORE_SESSIONMANAGER) << "closed file session at DC" << dcId;
90 qCDebug(TG_CORE_SESSIONMANAGER) << "remaining" << mFileSessions.count() << "file sessions, counting all DCs";
91 } else {
92 qCDebug(TG_CORE_SESSIONMANAGER) << "released file session at DC" << dcId << ", remaining" << resourcesAtDc << "resources";
93 }
94 } else if (mMainSession && mMainSession->sessionId() == sessionId) {
95 mMainSession->close();
96 }
97 }
98
onSessionClosed(qint64 sessionId)99 void SessionManager::onSessionClosed(qint64 sessionId) {
100 Session *session = mFileSessions.take(sessionId);
101 if (session) {
102 session->deleteLater();
103 } else if (mMainSession && mMainSession->sessionId() == sessionId) {
104 mMainSession->deleteLater();
105 }
106 }
107
mainSession()108 Session *SessionManager::mainSession() {
109 return mMainSession;
110 }
111
setMainSession(Session * session)112 void SessionManager::setMainSession(Session *session) {
113 mMainSession = session;
114 }
115
changeMainSessionToDc(DC * dc)116 void SessionManager::changeMainSessionToDc(DC *dc) {
117 // remove current main session that is connected to a wrong dc
118 if (mMainSession) {
119 mMainSession->close();
120 }
121 // create session and connect to dc, adding the signal of dc changed
122 mMainSession = createSession(dc);
123 connect(mMainSession, SIGNAL(sessionReady(DC*)), this, SIGNAL(mainSessionDcChanged(DC*)), Qt::UniqueConnection);
124 connect(mMainSession, SIGNAL(sessionReady(DC*)), this, SIGNAL(mainSessionReady()), Qt::UniqueConnection);
125 connect(mMainSession, SIGNAL(sessionClosed(qint64)), this, SIGNAL(mainSessionClosed()), Qt::UniqueConnection);
126 connectUpdatesSignals(mMainSession);
127 mMainSession->connectToServer();
128 }
129
createMainSessionToDc(DC * dc)130 void SessionManager::createMainSessionToDc(DC *dc) {
131 // create session and connect to dc
132 mMainSession = createSession(dc);
133 connect(mMainSession, SIGNAL(sessionReady(DC*)), this, SIGNAL(mainSessionReady()), Qt::UniqueConnection);
134 connect(mMainSession, SIGNAL(sessionClosed(qint64)), this, SIGNAL(mainSessionClosed()), Qt::UniqueConnection);
135 connectUpdatesSignals(mMainSession);
136 mMainSession->connectToServer();
137 }
138