data_group_call.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/timer.h"
  9. class PeerData;
  10. class ApiWrap;
  11. namespace Calls {
  12. struct ParticipantVideoParams;
  13. } // namespace Calls
  14. namespace Data {
  15. [[nodiscard]] const std::string &RtmpEndpointId();
  16. struct LastSpokeTimes {
  17. crl::time anything = 0;
  18. crl::time voice = 0;
  19. };
  20. struct GroupCallParticipant {
  21. not_null<PeerData*> peer;
  22. std::shared_ptr<Calls::ParticipantVideoParams> videoParams;
  23. TimeId date = 0;
  24. TimeId lastActive = 0;
  25. uint64 raisedHandRating = 0;
  26. uint32 ssrc = 0;
  27. int volume = 0;
  28. bool sounding : 1 = false;
  29. bool speaking : 1 = false;
  30. bool additionalSounding : 1 = false;
  31. bool additionalSpeaking : 1 = false;
  32. bool muted : 1 = false;
  33. bool mutedByMe : 1 = false;
  34. bool canSelfUnmute : 1 = false;
  35. bool onlyMinLoaded : 1 = false;
  36. bool videoJoined = false;
  37. bool applyVolumeFromMin = true;
  38. [[nodiscard]] const std::string &cameraEndpoint() const;
  39. [[nodiscard]] const std::string &screenEndpoint() const;
  40. [[nodiscard]] bool cameraPaused() const;
  41. [[nodiscard]] bool screenPaused() const;
  42. };
  43. class GroupCall final {
  44. public:
  45. GroupCall(
  46. not_null<PeerData*> peer,
  47. CallId id,
  48. CallId accessHash,
  49. TimeId scheduleDate,
  50. bool rtmp);
  51. ~GroupCall();
  52. [[nodiscard]] CallId id() const;
  53. [[nodiscard]] bool loaded() const;
  54. [[nodiscard]] bool rtmp() const;
  55. [[nodiscard]] bool listenersHidden() const;
  56. [[nodiscard]] not_null<PeerData*> peer() const;
  57. [[nodiscard]] MTPInputGroupCall input() const;
  58. [[nodiscard]] QString title() const {
  59. return _title.current();
  60. }
  61. [[nodiscard]] rpl::producer<QString> titleValue() const {
  62. return _title.value();
  63. }
  64. void setTitle(const QString &title) {
  65. _title = title;
  66. }
  67. [[nodiscard]] TimeId recordStartDate() const {
  68. return _recordStartDate.current();
  69. }
  70. [[nodiscard]] rpl::producer<TimeId> recordStartDateValue() const {
  71. return _recordStartDate.value();
  72. }
  73. [[nodiscard]] rpl::producer<TimeId> recordStartDateChanges() const {
  74. return _recordStartDate.changes();
  75. }
  76. [[nodiscard]] TimeId scheduleDate() const {
  77. return _scheduleDate.current();
  78. }
  79. [[nodiscard]] rpl::producer<TimeId> scheduleDateValue() const {
  80. return _scheduleDate.value();
  81. }
  82. [[nodiscard]] rpl::producer<TimeId> scheduleDateChanges() const {
  83. return _scheduleDate.changes();
  84. }
  85. [[nodiscard]] bool scheduleStartSubscribed() const {
  86. return _scheduleStartSubscribed.current();
  87. }
  88. [[nodiscard]] rpl::producer<bool> scheduleStartSubscribedValue() const {
  89. return _scheduleStartSubscribed.value();
  90. }
  91. [[nodiscard]] int unmutedVideoLimit() const {
  92. return _unmutedVideoLimit.current();
  93. }
  94. [[nodiscard]] bool recordVideo() const {
  95. return _recordVideo.current();
  96. }
  97. void setPeer(not_null<PeerData*> peer);
  98. using Participant = GroupCallParticipant;
  99. struct ParticipantUpdate {
  100. std::optional<Participant> was;
  101. std::optional<Participant> now;
  102. };
  103. static constexpr auto kSoundStatusKeptFor = crl::time(1500);
  104. [[nodiscard]] auto participants() const
  105. -> const std::vector<Participant> &;
  106. void requestParticipants();
  107. [[nodiscard]] bool participantsLoaded() const;
  108. [[nodiscard]] PeerData *participantPeerByAudioSsrc(uint32 ssrc) const;
  109. [[nodiscard]] const Participant *participantByPeer(
  110. not_null<PeerData*> peer) const;
  111. [[nodiscard]] const Participant *participantByEndpoint(
  112. const std::string &endpoint) const;
  113. [[nodiscard]] rpl::producer<> participantsReloaded();
  114. [[nodiscard]] auto participantUpdated() const
  115. -> rpl::producer<ParticipantUpdate>;
  116. [[nodiscard]] auto participantSpeaking() const
  117. -> rpl::producer<not_null<Participant*>>;
  118. void enqueueUpdate(const MTPUpdate &update);
  119. void applyLocalUpdate(
  120. const MTPDupdateGroupCallParticipants &update);
  121. void applyLastSpoke(uint32 ssrc, LastSpokeTimes when, crl::time now);
  122. void applyActiveUpdate(
  123. PeerId participantPeerId,
  124. LastSpokeTimes when,
  125. PeerData *participantPeerLoaded);
  126. void resolveParticipants(const base::flat_set<uint32> &ssrcs);
  127. [[nodiscard]] rpl::producer<
  128. not_null<const base::flat_map<
  129. uint32,
  130. LastSpokeTimes>*>> participantsResolved() const {
  131. return _participantsResolved.events();
  132. }
  133. [[nodiscard]] int fullCount() const;
  134. [[nodiscard]] rpl::producer<int> fullCountValue() const;
  135. void setInCall();
  136. void reload();
  137. void reloadIfStale();
  138. void processFullCall(const MTPphone_GroupCall &call);
  139. void setJoinMutedLocally(bool muted);
  140. [[nodiscard]] bool joinMuted() const;
  141. [[nodiscard]] bool canChangeJoinMuted() const;
  142. [[nodiscard]] bool joinedToTop() const;
  143. private:
  144. enum class ApplySliceSource {
  145. FullReloaded,
  146. SliceLoaded,
  147. UnknownLoaded,
  148. UpdateReceived,
  149. UpdateConstructed,
  150. };
  151. enum class QueuedType : uint8 {
  152. VersionedParticipant,
  153. Participant,
  154. Call,
  155. };
  156. [[nodiscard]] ApiWrap &api() const;
  157. void discard(const MTPDgroupCallDiscarded &data);
  158. [[nodiscard]] bool inCall() const;
  159. void applyParticipantsSlice(
  160. const QVector<MTPGroupCallParticipant> &list,
  161. ApplySliceSource sliceSource);
  162. void requestUnknownParticipants();
  163. void changePeerEmptyCallFlag();
  164. void checkFinishSpeakingByActive();
  165. void applyCallFields(const MTPDgroupCall &data);
  166. void applyEnqueuedUpdate(const MTPUpdate &update);
  167. void setServerParticipantsCount(int count);
  168. void computeParticipantsCount();
  169. void processQueuedUpdates();
  170. void processFullCallUsersChats(const MTPphone_GroupCall &call);
  171. void processFullCallFields(const MTPphone_GroupCall &call);
  172. [[nodiscard]] bool requestParticipantsAfterReload(
  173. const MTPphone_GroupCall &call) const;
  174. [[nodiscard]] bool processSavedFullCall();
  175. void finishParticipantsSliceRequest();
  176. [[nodiscard]] Participant *findParticipant(not_null<PeerData*> peer);
  177. const CallId _id = 0;
  178. const CallId _accessHash = 0;
  179. not_null<PeerData*> _peer;
  180. int _version = 0;
  181. mtpRequestId _participantsRequestId = 0;
  182. mtpRequestId _reloadRequestId = 0;
  183. crl::time _reloadLastFinished = 0;
  184. rpl::variable<QString> _title;
  185. base::flat_multi_map<
  186. std::pair<int, QueuedType>,
  187. MTPUpdate> _queuedUpdates;
  188. base::Timer _reloadByQueuedUpdatesTimer;
  189. std::optional<MTPphone_GroupCall> _savedFull;
  190. std::vector<Participant> _participants;
  191. base::flat_map<uint32, not_null<PeerData*>> _participantPeerByAudioSsrc;
  192. base::flat_map<not_null<PeerData*>, crl::time> _speakingByActiveFinishes;
  193. base::Timer _speakingByActiveFinishTimer;
  194. QString _nextOffset;
  195. int _serverParticipantsCount = 0;
  196. rpl::variable<int> _fullCount = 0;
  197. rpl::variable<int> _unmutedVideoLimit = 0;
  198. rpl::variable<bool> _recordVideo = 0;
  199. rpl::variable<TimeId> _recordStartDate = 0;
  200. rpl::variable<TimeId> _scheduleDate = 0;
  201. rpl::variable<bool> _scheduleStartSubscribed = false;
  202. base::flat_map<uint32, LastSpokeTimes> _unknownSpokenSsrcs;
  203. base::flat_map<PeerId, LastSpokeTimes> _unknownSpokenPeerIds;
  204. rpl::event_stream<
  205. not_null<const base::flat_map<
  206. uint32,
  207. LastSpokeTimes>*>> _participantsResolved;
  208. mtpRequestId _unknownParticipantPeersRequestId = 0;
  209. rpl::event_stream<ParticipantUpdate> _participantUpdates;
  210. rpl::event_stream<not_null<Participant*>> _participantSpeaking;
  211. rpl::event_stream<> _participantsReloaded;
  212. bool _joinMuted = false;
  213. bool _canChangeJoinMuted = true;
  214. bool _allParticipantsLoaded = false;
  215. bool _joinedToTop = false;
  216. bool _applyingQueuedUpdates = false;
  217. bool _rtmp = false;
  218. bool _listenersHidden = false;
  219. };
  220. } // namespace Data