Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
* Copyright (C) 2004-2021 Savoir-faire Linux Inc.
*
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
* Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package net.jami.model
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.subjects.BehaviorSubject
import io.reactivex.rxjava3.subjects.Subject
import net.jami.model.Call.CallStatus
import net.jami.model.Call.CallStatus.Companion.fromConferenceString
import java.util.*
import kotlin.math.min
class Conference {
class ParticipantInfo(val call: Call?, val contact: Contact, i: Map<String, String>) {
var x: Int = i["x"]?.toInt() ?: 0
var y: Int = i["y"]?.toInt() ?: 0
var w: Int = i["w"]?.toInt() ?: 0
var h: Int = i["h"]?.toInt() ?: 0
var videoMuted: Boolean = java.lang.Boolean.parseBoolean(i["videoMuted"])
var audioMuted: Boolean = java.lang.Boolean.parseBoolean(i["audioMuted"])
var isModerator: Boolean = java.lang.Boolean.parseBoolean(i["isModerator"])
val isEmpty: Boolean
get() = x == 0 && y == 0 && w == 0 && h == 0
}
private val mParticipantInfo: Subject<List<ParticipantInfo>> = BehaviorSubject.createDefault(emptyList())
private val mParticipantRecordingSet: MutableSet<Contact> = HashSet()
private val mParticipantRecording: Subject<Set<Contact>> = BehaviorSubject.createDefault(emptySet())
val id: String
private var mConfState: CallStatus? = null
private val mParticipants: ArrayList<Call>
private var mRecording: Boolean
var maximizedParticipant: Contact? = null
var isModerator = false
constructor(call: Call) : this(call.daemonIdString!!) {
mParticipants.add(call)
}
constructor(cID: String) {
id = cID
mParticipants = ArrayList()
mRecording = false
}
constructor(c: Conference) {
id = c.id
mConfState = c.mConfState
mParticipants = ArrayList(c.mParticipants)
mRecording = c.mRecording
}
val isRinging: Boolean
get() = mParticipants.isNotEmpty() && mParticipants[0].isRinging
val isConference: Boolean
get() = mParticipants.size > 1
val call: Call?
get() = if (!isConference) {
firstCall
} else null
val firstCall: Call?
get() = if (mParticipants.isNotEmpty()) {
mParticipants[0]
} else null
val pluginId: String
get() = "local"
val state: CallStatus?
get() = if (isSimpleCall) {
mParticipants[0].callStatus
} else mConfState
val confState: CallStatus?
get() = if (mParticipants.size == 1) {
mParticipants[0].callStatus
} else mConfState
val isSimpleCall: Boolean
get() = mParticipants.size == 1 && id == mParticipants[0].daemonIdString
fun setState(state: String) {
mConfState = fromConferenceString(state)
}
val participants: MutableList<Call>
get() = mParticipants
fun addParticipant(part: Call) {
mParticipants.add(part)
}
fun removeParticipant(toRemove: Call): Boolean {
return mParticipants.remove(toRemove)
}
operator fun contains(callID: String): Boolean {
for (participant in mParticipants)
if (participant.daemonIdString == callID) return true
fun getCallById(callID: String): Call? {
for (participant in mParticipants)
if (participant.daemonIdString == callID) return participant
return null
}
fun findCallByContact(uri: Uri): Call? {
val mUri = if (uri.host == "ring.dht") Uri.fromId(uri.rawRingId) else uri
if (call.contact?.uri == mUri)
return call
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
}
return null
}
val isIncoming: Boolean
get() = mParticipants.size == 1 && mParticipants[0].isIncoming
val isOnGoing: Boolean
get() = mParticipants.size == 1 && mParticipants[0].isOnGoing || mParticipants.size > 1
fun hasVideo(): Boolean {
for (call in mParticipants) if (!call.isAudioOnly) return true
return false
}
val timestampStart: Long
get() {
var t = Long.MAX_VALUE
for (call in mParticipants) t = min(call.timestamp, t)
return t
}
fun removeParticipants() {
mParticipants.clear()
}
fun setInfo(info: List<ParticipantInfo>) {
mParticipantInfo.onNext(info)
}
val participantInfo: Observable<List<ParticipantInfo>>
get() = mParticipantInfo
val participantRecording: Observable<Set<Contact>>
get() = mParticipantRecording
fun setParticipantRecording(contact: Contact, state: Boolean) {
if (state) {
mParticipantRecordingSet.add(contact)
} else {
mParticipantRecordingSet.remove(contact)
}
mParticipantRecording.onNext(mParticipantRecordingSet)
}
}