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 "data/data_pts_waiter.h"
11 #include "base/timer.h"
12 
13 class ApiWrap;
14 class History;
15 
16 namespace MTP {
17 class Error;
18 } // namespace MTP
19 
20 namespace Main {
21 class Session;
22 } // namespace Main
23 
24 namespace ChatHelpers {
25 struct EmojiInteractionsBunch;
26 } // namespace ChatHelpers
27 
28 namespace Api {
29 
30 class Updates final {
31 public:
32 	explicit Updates(not_null<Main::Session*> session);
33 
34 	[[nodiscard]] Main::Session &session() const;
35 	[[nodiscard]] ApiWrap &api() const;
36 
37 	void applyUpdates(
38 		const MTPUpdates &updates,
39 		uint64 sentMessageRandomId = 0);
40 	void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
41 	void applyUpdateNoPtsCheck(const MTPUpdate &update);
42 
43 	[[nodiscard]] int32 pts() const;
44 
45 	void updateOnline(crl::time lastNonIdleTime = 0);
46 	[[nodiscard]] bool isIdle() const;
47 	[[nodiscard]] rpl::producer<bool> isIdleValue() const;
48 	void checkIdleFinish(crl::time lastNonIdleTime = 0);
49 	bool lastWasOnline() const;
50 	crl::time lastSetOnline() const;
51 	bool isQuitPrevent();
52 
53 	bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates);
54 	bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdate &update);
55 	bool updateAndApply(int32 pts, int32 ptsCount);
56 
57 	void checkLastUpdate(bool afterSleep);
58 
59 	// ms <= 0 - stop timer
60 	void ptsWaiterStartTimerFor(ChannelData *channel, crl::time ms);
61 
62 	void getDifference();
63 	void requestChannelRangeDifference(not_null<History*> history);
64 
65 	void addActiveChat(rpl::producer<PeerData*> chat);
66 
67 private:
68 	enum class ChannelDifferenceRequest {
69 		Unknown,
70 		PtsGapOrShortPoll,
71 		AfterFail,
72 	};
73 
74 	enum class SkipUpdatePolicy {
75 		SkipNone,
76 		SkipMessageIds,
77 		SkipExceptGroupCallParticipants,
78 	};
79 
80 	struct ActiveChatTracker {
81 		PeerData *peer = nullptr;
82 		rpl::lifetime lifetime;
83 	};
84 
85 	void channelRangeDifferenceSend(
86 		not_null<ChannelData*> channel,
87 		MsgRange range,
88 		int32 pts);
89 	void channelRangeDifferenceDone(
90 		not_null<ChannelData*> channel,
91 		MsgRange range,
92 		const MTPupdates_ChannelDifference &result);
93 
94 	void updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline);
95 	void sendPing();
96 	void getDifferenceByPts();
97 	void getDifferenceAfterFail();
98 
requestingDifference()99 	[[nodiscard]] bool requestingDifference() const {
100 		return _ptsWaiter.requesting();
101 	}
102 	void getChannelDifference(
103 		not_null<ChannelData*> channel,
104 		ChannelDifferenceRequest from = ChannelDifferenceRequest::Unknown);
105 	void differenceDone(const MTPupdates_Difference &result);
106 	void differenceFail(const MTP::Error &error);
107 	void feedDifference(
108 		const MTPVector<MTPUser> &users,
109 		const MTPVector<MTPChat> &chats,
110 		const MTPVector<MTPMessage> &msgs,
111 		const MTPVector<MTPUpdate> &other);
112 	void stateDone(const MTPupdates_State &state);
113 	void setState(int32 pts, int32 date, int32 qts, int32 seq);
114 	void channelDifferenceDone(
115 		not_null<ChannelData*> channel,
116 		const MTPupdates_ChannelDifference &diff);
117 	void channelDifferenceFail(
118 		not_null<ChannelData*> channel,
119 		const MTP::Error &error);
120 	void failDifferenceStartTimerFor(ChannelData *channel);
121 	void feedChannelDifference(const MTPDupdates_channelDifference &data);
122 
123 	void mtpUpdateReceived(const MTPUpdates &updates);
124 	void mtpNewSessionCreated();
125 	void feedUpdateVector(
126 		const MTPVector<MTPUpdate> &updates,
127 		SkipUpdatePolicy policy = SkipUpdatePolicy::SkipNone);
128 	// Doesn't call sendHistoryChangeNotifications itself.
129 	void feedMessageIds(const MTPVector<MTPUpdate> &updates);
130 	// Doesn't call sendHistoryChangeNotifications itself.
131 	void feedUpdate(const MTPUpdate &update);
132 
133 	void applyGroupCallParticipantUpdates(const MTPUpdates &updates);
134 
135 	bool whenGetDiffChanged(
136 		ChannelData *channel,
137 		int32 ms,
138 		base::flat_map<not_null<ChannelData*>, crl::time> &whenMap,
139 		crl::time &curTime);
140 
141 	void handleSendActionUpdate(
142 		PeerId peerId,
143 		MsgId rootId,
144 		PeerId fromId,
145 		const MTPSendMessageAction &action);
146 	void handleEmojiInteraction(
147 		not_null<PeerData*> peer,
148 		const MTPDsendMessageEmojiInteraction &data);
149 	void handleSpeakingInCall(
150 		not_null<PeerData*> peer,
151 		PeerId participantPeerId,
152 		PeerData *participantPeerLoaded);
153 	void handleEmojiInteraction(
154 		not_null<PeerData*> peer,
155 		MsgId messageId,
156 		const QString &emoticon,
157 		ChatHelpers::EmojiInteractionsBunch bunch);
158 	void handleEmojiInteraction(
159 		not_null<PeerData*> peer,
160 		const QString &emoticon);
161 
162 	const not_null<Main::Session*> _session;
163 
164 	int32 _updatesDate = 0;
165 	int32 _updatesQts = -1;
166 	int32 _updatesSeq = 0;
167 	base::Timer _noUpdatesTimer;
168 	base::Timer _onlineTimer;
169 
170 	PtsWaiter _ptsWaiter;
171 
172 	base::flat_map<not_null<ChannelData*>, crl::time> _whenGetDiffByPts;
173 	base::flat_map<not_null<ChannelData*>, crl::time> _whenGetDiffAfterFail;
174 	crl::time _getDifferenceTimeByPts = 0;
175 	crl::time _getDifferenceTimeAfterFail = 0;
176 
177 	base::Timer _byPtsTimer;
178 
179 	base::flat_map<int32, MTPUpdates> _bySeqUpdates;
180 	base::Timer _bySeqTimer;
181 
182 	base::Timer _byMinChannelTimer;
183 
184 	// growing timeout for getDifference calls, if it fails
185 	crl::time _failDifferenceTimeout = 1;
186 	// growing timeout for getChannelDifference calls, if it fails
187 	base::flat_map<
188 		not_null<ChannelData*>,
189 		crl::time> _channelFailDifferenceTimeout;
190 	base::Timer _failDifferenceTimer;
191 
192 	base::flat_map<
193 		not_null<ChannelData*>,
194 		mtpRequestId> _rangeDifferenceRequests;
195 
196 	crl::time _lastUpdateTime = 0;
197 	bool _handlingChannelDifference = false;
198 
199 	base::flat_map<int, ActiveChatTracker> _activeChats;
200 	base::flat_map<
201 		not_null<PeerData*>,
202 		base::flat_map<PeerId, crl::time>> _pendingSpeakingCallParticipants;
203 
204 	mtpRequestId _onlineRequest = 0;
205 	base::Timer _idleFinishTimer;
206 	crl::time _lastSetOnline = 0;
207 	bool _lastWasOnline = false;
208 	rpl::variable<bool> _isIdle = false;
209 
210 	rpl::lifetime _lifetime;
211 
212 };
213 
214 } // namespace Api
215