1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4 
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #pragma once
9 
10 #include "mtproto/sender.h"
11 
12 namespace crl {
13 class semaphore;
14 } // namespace crl
15 
16 namespace Platform {
17 enum class PermissionType;
18 } // namespace Platform
19 
20 namespace Media::Audio {
21 class Track;
22 } // namespace Media::Audio
23 
24 namespace Main {
25 class Session;
26 } // namespace Main
27 
28 namespace Calls::Group {
29 struct JoinInfo;
30 class Panel;
31 class ChooseJoinAsProcess;
32 } // namespace Calls::Group
33 
34 namespace tgcalls {
35 class VideoCaptureInterface;
36 } // namespace tgcalls
37 
38 namespace Calls {
39 
40 class Call;
41 enum class CallType;
42 class GroupCall;
43 class Panel;
44 struct DhConfig;
45 
46 class Instance final : public base::has_weak_ptr {
47 public:
48 	Instance();
49 	~Instance();
50 
51 	void startOutgoingCall(not_null<UserData*> user, bool video);
52 	void startOrJoinGroupCall(
53 		not_null<PeerData*> peer,
54 		const QString &joinHash = QString(),
55 		bool confirmNeeded = false);
56 	void handleUpdate(
57 		not_null<Main::Session*> session,
58 		const MTPUpdate &update);
59 
60 	// Called by Data::GroupCall when it is appropriate by the 'version'.
61 	void applyGroupCallUpdateChecked(
62 		not_null<Main::Session*> session,
63 		const MTPUpdate &update);
64 
65 	void showInfoPanel(not_null<Call*> call);
66 	void showInfoPanel(not_null<GroupCall*> call);
67 	[[nodiscard]] Call *currentCall() const;
68 	[[nodiscard]] rpl::producer<Call*> currentCallValue() const;
69 	[[nodiscard]] GroupCall *currentGroupCall() const;
70 	[[nodiscard]] rpl::producer<GroupCall*> currentGroupCallValue() const;
71 	[[nodiscard]] bool inCall() const;
72 	[[nodiscard]] bool inGroupCall() const;
73 	[[nodiscard]] bool hasActivePanel(
74 		not_null<Main::Session*> session) const;
75 	bool activateCurrentCall(const QString &joinHash = QString());
76 	bool minimizeCurrentActiveCall();
77 	bool closeCurrentActiveCall();
78 	[[nodiscard]] auto getVideoCapture(
79 		std::optional<QString> deviceId = std::nullopt,
80 		bool isScreenCapture = false)
81 		-> std::shared_ptr<tgcalls::VideoCaptureInterface>;
82 	void requestPermissionsOrFail(Fn<void()> onSuccess, bool video = true);
83 
84 	void setCurrentAudioDevice(bool input, const QString &deviceId);
85 
86 	[[nodiscard]] FnMut<void()> addAsyncWaiter();
87 
88 	[[nodiscard]] bool isQuitPrevent();
89 
90 private:
91 	class Delegate;
92 	friend class Delegate;
93 
94 	not_null<Media::Audio::Track*> ensureSoundLoaded(const QString &key);
95 	void playSoundOnce(const QString &key);
96 
97 	void createCall(not_null<UserData*> user, CallType type, bool video);
98 	void destroyCall(not_null<Call*> call);
99 
100 	void createGroupCall(
101 		Group::JoinInfo info,
102 		const MTPInputGroupCall &inputCall);
103 	void destroyGroupCall(not_null<GroupCall*> call);
104 
105 	void requestPermissionOrFail(
106 		Platform::PermissionType type,
107 		Fn<void()> onSuccess);
108 
109 	void refreshDhConfig();
110 	void refreshServerConfig(not_null<Main::Session*> session);
111 	bytes::const_span updateDhConfig(const MTPmessages_DhConfig &data);
112 
113 	void destroyCurrentCall();
114 	void handleCallUpdate(
115 		not_null<Main::Session*> session,
116 		const MTPPhoneCall &call);
117 	void handleSignalingData(
118 		not_null<Main::Session*> session,
119 		const MTPDupdatePhoneCallSignalingData &data);
120 	void handleGroupCallUpdate(
121 		not_null<Main::Session*> session,
122 		const MTPUpdate &update);
123 
124 	const std::unique_ptr<Delegate> _delegate;
125 	const std::unique_ptr<DhConfig> _cachedDhConfig;
126 
127 	crl::time _lastServerConfigUpdateTime = 0;
128 	base::weak_ptr<Main::Session> _serverConfigRequestSession;
129 	std::weak_ptr<tgcalls::VideoCaptureInterface> _videoCapture;
130 
131 	std::unique_ptr<Call> _currentCall;
132 	rpl::event_stream<Call*> _currentCallChanges;
133 	std::unique_ptr<Panel> _currentCallPanel;
134 
135 	std::unique_ptr<GroupCall> _currentGroupCall;
136 	rpl::event_stream<GroupCall*> _currentGroupCallChanges;
137 	std::unique_ptr<Group::Panel> _currentGroupCallPanel;
138 
139 	base::flat_map<QString, std::unique_ptr<Media::Audio::Track>> _tracks;
140 
141 	const std::unique_ptr<Group::ChooseJoinAsProcess> _chooseJoinAs;
142 
143 	base::flat_set<std::unique_ptr<crl::semaphore>> _asyncWaiters;
144 
145 };
146 
147 } // namespace Calls
148