mtp_instance.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 "mtproto/details/mtproto_serialized_request.h"
  9. #include "mtproto/mtproto_response.h"
  10. namespace MTP {
  11. namespace details {
  12. class Dcenter;
  13. class Session;
  14. [[nodiscard]] int GetNextRequestId();
  15. } // namespace details
  16. class DcOptions;
  17. class Config;
  18. struct ConfigFields;
  19. class AuthKey;
  20. using AuthKeyPtr = std::shared_ptr<AuthKey>;
  21. using AuthKeysList = std::vector<AuthKeyPtr>;
  22. enum class Environment : uchar;
  23. class Instance : public QObject {
  24. Q_OBJECT
  25. public:
  26. struct Fields {
  27. Fields();
  28. Fields(Fields &&other);
  29. Fields &operator=(Fields &&other);
  30. ~Fields();
  31. static constexpr auto kNoneMainDc = -1;
  32. static constexpr auto kNotSetMainDc = 0;
  33. static constexpr auto kDefaultMainDc = 2;
  34. static constexpr auto kTemporaryMainDc = 1000;
  35. std::unique_ptr<Config> config;
  36. DcId mainDcId = kNotSetMainDc;
  37. AuthKeysList keys;
  38. QString deviceModel;
  39. QString systemVersion;
  40. };
  41. enum class Mode {
  42. Normal,
  43. KeysDestroyer,
  44. };
  45. Instance(Mode mode, Fields &&fields);
  46. Instance(const Instance &other) = delete;
  47. Instance &operator=(const Instance &other) = delete;
  48. ~Instance();
  49. void resolveProxyDomain(const QString &host);
  50. void setGoodProxyDomain(const QString &host, const QString &ip);
  51. void suggestMainDcId(DcId mainDcId);
  52. void setMainDcId(DcId mainDcId);
  53. [[nodiscard]] DcId mainDcId() const;
  54. [[nodiscard]] rpl::producer<DcId> mainDcIdValue() const;
  55. [[nodiscard]] QString systemLangCode() const;
  56. [[nodiscard]] QString cloudLangCode() const;
  57. [[nodiscard]] QString langPackName() const;
  58. [[nodiscard]] rpl::producer<> writeKeysRequests() const;
  59. [[nodiscard]] rpl::producer<> allKeysDestroyed() const;
  60. // Thread-safe.
  61. [[nodiscard]] Config &config() const;
  62. [[nodiscard]] const ConfigFields &configValues() const;
  63. [[nodiscard]] DcOptions &dcOptions() const;
  64. [[nodiscard]] Environment environment() const;
  65. [[nodiscard]] bool isTestMode() const;
  66. [[nodiscard]] QString deviceModel() const;
  67. [[nodiscard]] QString systemVersion() const;
  68. // Main thread.
  69. void dcPersistentKeyChanged(DcId dcId, const AuthKeyPtr &persistentKey);
  70. void dcTemporaryKeyChanged(DcId dcId);
  71. [[nodiscard]] rpl::producer<DcId> dcTemporaryKeyChanged() const;
  72. [[nodiscard]] AuthKeysList getKeysForWrite() const;
  73. void addKeysForDestroy(AuthKeysList &&keys);
  74. void restart();
  75. void restart(ShiftedDcId shiftedDcId);
  76. int32 dcstate(ShiftedDcId shiftedDcId = 0);
  77. QString dctransport(ShiftedDcId shiftedDcId = 0);
  78. void ping();
  79. void cancel(mtpRequestId requestId);
  80. int32 state(mtpRequestId requestId); // < 0 means waiting for such count of ms
  81. // Main thread.
  82. void killSession(ShiftedDcId shiftedDcId);
  83. void stopSession(ShiftedDcId shiftedDcId);
  84. void reInitConnection(DcId dcId);
  85. void logout(Fn<void()> done);
  86. void setUpdatesHandler(Fn<void(const Response&)> handler);
  87. void setGlobalFailHandler(
  88. Fn<void(const Error&, const Response&)> handler);
  89. void setStateChangedHandler(
  90. Fn<void(ShiftedDcId shiftedDcId, int32 state)> handler);
  91. void setSessionResetHandler(Fn<void(ShiftedDcId shiftedDcId)> handler);
  92. void clearGlobalHandlers();
  93. void onStateChange(ShiftedDcId shiftedDcId, int32 state);
  94. void onSessionReset(ShiftedDcId shiftedDcId);
  95. [[nodiscard]] bool hasCallback(mtpRequestId requestId) const;
  96. void processCallback(const Response &response);
  97. void processUpdate(const Response &message);
  98. // return true if need to clean request data
  99. bool rpcErrorOccured(
  100. const Response &response,
  101. const FailHandler &onFail,
  102. const Error &err);
  103. // Thread-safe.
  104. bool isKeysDestroyer() const;
  105. void keyWasPossiblyDestroyed(ShiftedDcId shiftedDcId);
  106. // Main thread.
  107. void keyDestroyedOnServer(ShiftedDcId shiftedDcId, uint64 keyId);
  108. void requestConfig();
  109. void requestConfigIfOld();
  110. void requestCDNConfig();
  111. void setUserPhone(const QString &phone);
  112. void badConfigurationError();
  113. void restartedByTimeout(ShiftedDcId shiftedDcId);
  114. [[nodiscard]] rpl::producer<ShiftedDcId> restartsByTimeout() const;
  115. [[nodiscard]] auto nonPremiumDelayedRequests() const
  116. -> rpl::producer<mtpRequestId>;
  117. void syncHttpUnixtime();
  118. void sendAnything(ShiftedDcId shiftedDcId = 0, crl::time msCanWait = 0);
  119. template <typename Request>
  120. mtpRequestId send(
  121. const Request &request,
  122. ResponseHandler &&callbacks = {},
  123. ShiftedDcId shiftedDcId = 0,
  124. crl::time msCanWait = 0,
  125. mtpRequestId afterRequestId = 0,
  126. mtpRequestId overrideRequestId = 0) {
  127. const auto requestId = overrideRequestId
  128. ? overrideRequestId
  129. : details::GetNextRequestId();
  130. sendSerialized(
  131. requestId,
  132. details::SerializedRequest::Serialize(request),
  133. std::move(callbacks),
  134. shiftedDcId,
  135. msCanWait,
  136. afterRequestId);
  137. return requestId;
  138. }
  139. template <typename Request>
  140. mtpRequestId send(
  141. const Request &request,
  142. DoneHandler &&onDone,
  143. FailHandler &&onFail = nullptr,
  144. ShiftedDcId shiftedDcId = 0,
  145. crl::time msCanWait = 0,
  146. mtpRequestId afterRequestId = 0,
  147. mtpRequestId overrideRequestId = 0) {
  148. return send(
  149. request,
  150. ResponseHandler{ std::move(onDone), std::move(onFail) },
  151. shiftedDcId,
  152. msCanWait,
  153. afterRequestId,
  154. overrideRequestId);
  155. }
  156. template <typename Request>
  157. mtpRequestId sendProtocolMessage(
  158. ShiftedDcId shiftedDcId,
  159. const Request &request) {
  160. const auto requestId = details::GetNextRequestId();
  161. sendRequest(
  162. requestId,
  163. details::SerializedRequest::Serialize(request),
  164. {},
  165. shiftedDcId,
  166. 0,
  167. false,
  168. 0);
  169. return requestId;
  170. }
  171. void sendSerialized(
  172. mtpRequestId requestId,
  173. details::SerializedRequest &&request,
  174. ResponseHandler &&callbacks,
  175. ShiftedDcId shiftedDcId,
  176. crl::time msCanWait,
  177. mtpRequestId afterRequestId) {
  178. const auto needsLayer = true;
  179. sendRequest(
  180. requestId,
  181. std::move(request),
  182. std::move(callbacks),
  183. shiftedDcId,
  184. msCanWait,
  185. needsLayer,
  186. afterRequestId);
  187. }
  188. [[nodiscard]] rpl::lifetime &lifetime();
  189. Q_SIGNALS:
  190. void proxyDomainResolved(
  191. QString host,
  192. QStringList ips,
  193. qint64 expireAt);
  194. private:
  195. void sendRequest(
  196. mtpRequestId requestId,
  197. details::SerializedRequest &&request,
  198. ResponseHandler &&callbacks,
  199. ShiftedDcId shiftedDcId,
  200. crl::time msCanWait,
  201. bool needsLayer,
  202. mtpRequestId afterRequestId);
  203. class Private;
  204. const std::unique_ptr<Private> _private;
  205. };
  206. } // namespace MTP