calls_call.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
  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. #include "calls/calls_call.h"
  8. #include "apiwrap.h"
  9. #include "base/openssl_help.h"
  10. #include "base/platform/base_platform_info.h"
  11. #include "base/random.h"
  12. #include "boxes/abstract_box.h"
  13. #include "calls/calls_instance.h"
  14. #include "calls/calls_panel.h"
  15. #include "core/application.h"
  16. #include "core/core_settings.h"
  17. #include "data/data_session.h"
  18. #include "data/data_user.h"
  19. #include "lang/lang_keys.h"
  20. #include "main/main_app_config.h"
  21. #include "main/main_session.h"
  22. #include "media/audio/media_audio_track.h"
  23. #include "mtproto/mtproto_config.h"
  24. #include "mtproto/mtproto_dh_utils.h"
  25. #include "ui/boxes/confirm_box.h"
  26. #include "ui/boxes/rate_call_box.h"
  27. #include "webrtc/webrtc_create_adm.h"
  28. #include "webrtc/webrtc_environment.h"
  29. #include "webrtc/webrtc_video_track.h"
  30. #include "window/window_controller.h"
  31. #include <tgcalls/Instance.h>
  32. #include <tgcalls/VideoCaptureInterface.h>
  33. #include <tgcalls/StaticThreads.h>
  34. namespace tgcalls {
  35. class InstanceImpl;
  36. class InstanceV2Impl;
  37. class InstanceV2ReferenceImpl;
  38. class InstanceImplLegacy;
  39. void SetLegacyGlobalServerConfig(const std::string &serverConfig);
  40. } // namespace tgcalls
  41. namespace Calls {
  42. namespace {
  43. constexpr auto kMinLayer = 65;
  44. constexpr auto kHangupTimeoutMs = 5000;
  45. constexpr auto kSha256Size = 32;
  46. constexpr auto kAuthKeySize = 256;
  47. const auto kDefaultVersion = "2.4.4"_q;
  48. const auto Register = tgcalls::Register<tgcalls::InstanceImpl>();
  49. const auto RegisterV2 = tgcalls::Register<tgcalls::InstanceV2Impl>();
  50. const auto RegV2Ref = tgcalls::Register<tgcalls::InstanceV2ReferenceImpl>();
  51. const auto RegisterLegacy = tgcalls::Register<tgcalls::InstanceImplLegacy>();
  52. [[nodiscard]] base::flat_set<int64> CollectEndpointIds(
  53. const QVector<MTPPhoneConnection> &list) {
  54. auto result = base::flat_set<int64>();
  55. result.reserve(list.size());
  56. for (const auto &connection : list) {
  57. connection.match([&](const MTPDphoneConnection &data) {
  58. result.emplace(int64(data.vid().v));
  59. }, [](const MTPDphoneConnectionWebrtc &) {
  60. });
  61. }
  62. return result;
  63. }
  64. void AppendEndpoint(
  65. std::vector<tgcalls::Endpoint> &list,
  66. const MTPPhoneConnection &connection) {
  67. connection.match([&](const MTPDphoneConnection &data) {
  68. if (data.vpeer_tag().v.length() != 16 || data.is_tcp()) {
  69. return;
  70. }
  71. tgcalls::Endpoint endpoint = {
  72. .endpointId = (int64_t)data.vid().v,
  73. .host = tgcalls::EndpointHost{
  74. .ipv4 = data.vip().v.toStdString(),
  75. .ipv6 = data.vipv6().v.toStdString() },
  76. .port = (uint16_t)data.vport().v,
  77. .type = tgcalls::EndpointType::UdpRelay,
  78. };
  79. const auto tag = data.vpeer_tag().v;
  80. if (tag.size() >= 16) {
  81. memcpy(endpoint.peerTag, tag.data(), 16);
  82. }
  83. list.push_back(std::move(endpoint));
  84. }, [&](const MTPDphoneConnectionWebrtc &data) {
  85. });
  86. }
  87. void AppendServer(
  88. std::vector<tgcalls::RtcServer> &list,
  89. const MTPPhoneConnection &connection,
  90. const base::flat_set<int64> &ids) {
  91. connection.match([&](const MTPDphoneConnection &data) {
  92. const auto hex = [](const QByteArray &value) {
  93. const auto digit = [](uchar c) {
  94. return char((c < 10) ? ('0' + c) : ('a' + c - 10));
  95. };
  96. auto result = std::string();
  97. result.reserve(value.size() * 2);
  98. for (const auto ch : value) {
  99. result += digit(uchar(ch) / 16);
  100. result += digit(uchar(ch) % 16);
  101. }
  102. return result;
  103. };
  104. const auto host = data.vip().v;
  105. const auto hostv6 = data.vipv6().v;
  106. const auto port = uint16_t(data.vport().v);
  107. const auto username = std::string("reflector");
  108. const auto password = hex(data.vpeer_tag().v);
  109. const auto i = ids.find(int64(data.vid().v));
  110. Assert(i != end(ids));
  111. const auto id = uint8_t((i - begin(ids)) + 1);
  112. const auto pushTurn = [&](const QString &host) {
  113. list.push_back(tgcalls::RtcServer{
  114. .id = id,
  115. .host = host.toStdString(),
  116. .port = port,
  117. .login = username,
  118. .password = password,
  119. .isTurn = true,
  120. .isTcp = data.is_tcp(),
  121. });
  122. };
  123. pushTurn(host);
  124. pushTurn(hostv6);
  125. }, [&](const MTPDphoneConnectionWebrtc &data) {
  126. const auto host = qs(data.vip());
  127. const auto hostv6 = qs(data.vipv6());
  128. const auto port = uint16_t(data.vport().v);
  129. if (data.is_stun()) {
  130. const auto pushStun = [&](const QString &host) {
  131. if (host.isEmpty()) {
  132. return;
  133. }
  134. list.push_back(tgcalls::RtcServer{
  135. .host = host.toStdString(),
  136. .port = port,
  137. .isTurn = false
  138. });
  139. };
  140. pushStun(host);
  141. pushStun(hostv6);
  142. }
  143. const auto username = qs(data.vusername());
  144. const auto password = qs(data.vpassword());
  145. if (data.is_turn() && !username.isEmpty() && !password.isEmpty()) {
  146. const auto pushTurn = [&](const QString &host) {
  147. list.push_back(tgcalls::RtcServer{
  148. .host = host.toStdString(),
  149. .port = port,
  150. .login = username.toStdString(),
  151. .password = password.toStdString(),
  152. .isTurn = true,
  153. });
  154. };
  155. pushTurn(host);
  156. pushTurn(hostv6);
  157. }
  158. });
  159. }
  160. constexpr auto kFingerprintDataSize = 256;
  161. uint64 ComputeFingerprint(bytes::const_span authKey) {
  162. Expects(authKey.size() == kFingerprintDataSize);
  163. auto hash = openssl::Sha1(authKey);
  164. return (gsl::to_integer<uint64>(hash[19]) << 56)
  165. | (gsl::to_integer<uint64>(hash[18]) << 48)
  166. | (gsl::to_integer<uint64>(hash[17]) << 40)
  167. | (gsl::to_integer<uint64>(hash[16]) << 32)
  168. | (gsl::to_integer<uint64>(hash[15]) << 24)
  169. | (gsl::to_integer<uint64>(hash[14]) << 16)
  170. | (gsl::to_integer<uint64>(hash[13]) << 8)
  171. | (gsl::to_integer<uint64>(hash[12]));
  172. }
  173. [[nodiscard]] QVector<MTPstring> WrapVersions(
  174. const std::vector<std::string> &data) {
  175. return ranges::views::all(
  176. data
  177. ) | ranges::views::transform([=](const std::string &string) {
  178. return MTP_string(string);
  179. }) | ranges::to<QVector<MTPstring>>;
  180. }
  181. [[nodiscard]] QVector<MTPstring> CollectVersionsForApi() {
  182. return WrapVersions(tgcalls::Meta::Versions() | ranges::actions::reverse);
  183. }
  184. [[nodiscard]] Webrtc::VideoState StartVideoState(bool enabled) {
  185. using State = Webrtc::VideoState;
  186. return enabled ? State::Active : State::Inactive;
  187. }
  188. } // namespace
  189. Call::Call(
  190. not_null<Delegate*> delegate,
  191. not_null<UserData*> user,
  192. Type type,
  193. bool video)
  194. : _delegate(delegate)
  195. , _user(user)
  196. , _api(&_user->session().mtp())
  197. , _type(type)
  198. , _discardByTimeoutTimer([=] { hangup(); })
  199. , _playbackDeviceId(
  200. &Core::App().mediaDevices(),
  201. Webrtc::DeviceType::Playback,
  202. Webrtc::DeviceIdValueWithFallback(
  203. Core::App().settings().callPlaybackDeviceIdValue(),
  204. Core::App().settings().playbackDeviceIdValue()))
  205. , _captureDeviceId(
  206. &Core::App().mediaDevices(),
  207. Webrtc::DeviceType::Capture,
  208. Webrtc::DeviceIdValueWithFallback(
  209. Core::App().settings().callCaptureDeviceIdValue(),
  210. Core::App().settings().captureDeviceIdValue()))
  211. , _cameraDeviceId(
  212. &Core::App().mediaDevices(),
  213. Webrtc::DeviceType::Camera,
  214. Core::App().settings().cameraDeviceIdValue())
  215. , _videoIncoming(
  216. std::make_unique<Webrtc::VideoTrack>(
  217. StartVideoState(video)))
  218. , _videoOutgoing(
  219. std::make_unique<Webrtc::VideoTrack>(
  220. StartVideoState(video))) {
  221. if (_type == Type::Outgoing) {
  222. setState(State::WaitingUserConfirmation);
  223. } else {
  224. const auto &config = _user->session().serverConfig();
  225. _discardByTimeoutTimer.callOnce(config.callRingTimeoutMs);
  226. startWaitingTrack();
  227. }
  228. setupMediaDevices();
  229. setupOutgoingVideo();
  230. }
  231. void Call::generateModExpFirst(bytes::const_span randomSeed) {
  232. auto first = MTP::CreateModExp(_dhConfig.g, _dhConfig.p, randomSeed);
  233. if (first.modexp.empty()) {
  234. LOG(("Call Error: Could not compute mod-exp first."));
  235. finish(FinishType::Failed);
  236. return;
  237. }
  238. _randomPower = std::move(first.randomPower);
  239. if (_type == Type::Incoming) {
  240. _gb = std::move(first.modexp);
  241. } else {
  242. _ga = std::move(first.modexp);
  243. _gaHash = openssl::Sha256(_ga);
  244. }
  245. }
  246. bool Call::isIncomingWaiting() const {
  247. if (type() != Call::Type::Incoming) {
  248. return false;
  249. }
  250. return (state() == State::Starting)
  251. || (state() == State::WaitingIncoming);
  252. }
  253. void Call::start(bytes::const_span random) {
  254. // Save config here, because it is possible that it changes between
  255. // different usages inside the same call.
  256. _dhConfig = _delegate->getDhConfig();
  257. Assert(_dhConfig.g != 0);
  258. Assert(!_dhConfig.p.empty());
  259. generateModExpFirst(random);
  260. const auto state = _state.current();
  261. if (state == State::Starting || state == State::Requesting) {
  262. if (_type == Type::Outgoing) {
  263. startOutgoing();
  264. } else {
  265. startIncoming();
  266. }
  267. } else if (state == State::ExchangingKeys
  268. && _answerAfterDhConfigReceived) {
  269. answer();
  270. }
  271. }
  272. void Call::startOutgoing() {
  273. Expects(_type == Type::Outgoing);
  274. Expects(_state.current() == State::Requesting);
  275. Expects(_gaHash.size() == kSha256Size);
  276. const auto flags = _videoCapture
  277. ? MTPphone_RequestCall::Flag::f_video
  278. : MTPphone_RequestCall::Flag(0);
  279. _api.request(MTPphone_RequestCall(
  280. MTP_flags(flags),
  281. _user->inputUser,
  282. MTPInputGroupCall(),
  283. MTP_int(base::RandomValue<int32>()),
  284. MTP_bytes(_gaHash),
  285. MTP_phoneCallProtocol(
  286. MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p
  287. | MTPDphoneCallProtocol::Flag::f_udp_reflector),
  288. MTP_int(kMinLayer),
  289. MTP_int(tgcalls::Meta::MaxLayer()),
  290. MTP_vector(CollectVersionsForApi()))
  291. )).done([=](const MTPphone_PhoneCall &result) {
  292. Expects(result.type() == mtpc_phone_phoneCall);
  293. setState(State::Waiting);
  294. const auto &call = result.c_phone_phoneCall();
  295. _user->session().data().processUsers(call.vusers());
  296. if (call.vphone_call().type() != mtpc_phoneCallWaiting) {
  297. LOG(("Call Error: Expected phoneCallWaiting in response to "
  298. "phone.requestCall()"));
  299. finish(FinishType::Failed);
  300. return;
  301. }
  302. const auto &phoneCall = call.vphone_call();
  303. const auto &waitingCall = phoneCall.c_phoneCallWaiting();
  304. _id = waitingCall.vid().v;
  305. _accessHash = waitingCall.vaccess_hash().v;
  306. if (_finishAfterRequestingCall != FinishType::None) {
  307. if (_finishAfterRequestingCall == FinishType::Failed) {
  308. finish(_finishAfterRequestingCall);
  309. } else {
  310. hangup();
  311. }
  312. return;
  313. }
  314. const auto &config = _user->session().serverConfig();
  315. _discardByTimeoutTimer.callOnce(config.callReceiveTimeoutMs);
  316. handleUpdate(phoneCall);
  317. }).fail([this](const MTP::Error &error) {
  318. handleRequestError(error.type());
  319. }).send();
  320. }
  321. void Call::startIncoming() {
  322. Expects(_type == Type::Incoming);
  323. Expects(_state.current() == State::Starting);
  324. _api.request(MTPphone_ReceivedCall(
  325. MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash))
  326. )).done([=] {
  327. if (_state.current() == State::Starting) {
  328. setState(State::WaitingIncoming);
  329. }
  330. }).fail([=](const MTP::Error &error) {
  331. handleRequestError(error.type());
  332. }).send();
  333. }
  334. void Call::applyUserConfirmation() {
  335. if (_state.current() == State::WaitingUserConfirmation) {
  336. setState(State::Requesting);
  337. }
  338. }
  339. void Call::answer() {
  340. const auto video = isSharingVideo();
  341. _delegate->callRequestPermissionsOrFail(crl::guard(this, [=] {
  342. actuallyAnswer();
  343. }), video);
  344. }
  345. void Call::actuallyAnswer() {
  346. Expects(_type == Type::Incoming);
  347. const auto state = _state.current();
  348. if (state != State::Starting && state != State::WaitingIncoming) {
  349. if (state != State::ExchangingKeys
  350. || !_answerAfterDhConfigReceived) {
  351. return;
  352. }
  353. }
  354. setState(State::ExchangingKeys);
  355. if (_gb.empty()) {
  356. _answerAfterDhConfigReceived = true;
  357. return;
  358. } else {
  359. _answerAfterDhConfigReceived = false;
  360. }
  361. _api.request(MTPphone_AcceptCall(
  362. MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)),
  363. MTP_bytes(_gb),
  364. MTP_phoneCallProtocol(
  365. MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p
  366. | MTPDphoneCallProtocol::Flag::f_udp_reflector),
  367. MTP_int(kMinLayer),
  368. MTP_int(tgcalls::Meta::MaxLayer()),
  369. MTP_vector(CollectVersionsForApi()))
  370. )).done([=](const MTPphone_PhoneCall &result) {
  371. Expects(result.type() == mtpc_phone_phoneCall);
  372. const auto &call = result.c_phone_phoneCall();
  373. _user->session().data().processUsers(call.vusers());
  374. if (call.vphone_call().type() != mtpc_phoneCallWaiting) {
  375. LOG(("Call Error: "
  376. "Not phoneCallWaiting in response to phone.acceptCall."));
  377. finish(FinishType::Failed);
  378. return;
  379. }
  380. handleUpdate(call.vphone_call());
  381. }).fail([=](const MTP::Error &error) {
  382. handleRequestError(error.type());
  383. }).send();
  384. }
  385. void Call::captureMuteChanged(bool mute) {
  386. setMuted(mute);
  387. }
  388. rpl::producer<Webrtc::DeviceResolvedId> Call::captureMuteDeviceId() {
  389. return _captureDeviceId.value();
  390. }
  391. void Call::setMuted(bool mute) {
  392. _muted = mute;
  393. if (_instance) {
  394. _instance->setMuteMicrophone(mute);
  395. }
  396. }
  397. void Call::setupMediaDevices() {
  398. _playbackDeviceId.changes() | rpl::filter([=] {
  399. return _instance && _setDeviceIdCallback;
  400. }) | rpl::start_with_next([=](const Webrtc::DeviceResolvedId &deviceId) {
  401. _setDeviceIdCallback(deviceId);
  402. // Value doesn't matter here, just trigger reading of the new value.
  403. _instance->setAudioOutputDevice(deviceId.value.toStdString());
  404. }, _lifetime);
  405. _captureDeviceId.changes() | rpl::filter([=] {
  406. return _instance && _setDeviceIdCallback;
  407. }) | rpl::start_with_next([=](const Webrtc::DeviceResolvedId &deviceId) {
  408. _setDeviceIdCallback(deviceId);
  409. // Value doesn't matter here, just trigger reading of the new value.
  410. _instance->setAudioInputDevice(deviceId.value.toStdString());
  411. }, _lifetime);
  412. }
  413. void Call::setupOutgoingVideo() {
  414. const auto cameraId = [] {
  415. return Core::App().mediaDevices().defaultId(
  416. Webrtc::DeviceType::Camera);
  417. };
  418. const auto started = _videoOutgoing->state();
  419. if (cameraId().isEmpty()) {
  420. _videoOutgoing->setState(Webrtc::VideoState::Inactive);
  421. }
  422. _videoOutgoing->stateValue(
  423. ) | rpl::start_with_next([=](Webrtc::VideoState state) {
  424. if (state != Webrtc::VideoState::Inactive
  425. && cameraId().isEmpty()
  426. && !_videoCaptureIsScreencast) {
  427. _errors.fire({ ErrorType::NoCamera });
  428. _videoOutgoing->setState(Webrtc::VideoState::Inactive);
  429. } else if (_state.current() != State::Established
  430. && (state != Webrtc::VideoState::Inactive)
  431. && (started == Webrtc::VideoState::Inactive)) {
  432. _errors.fire({ ErrorType::NotStartedCall });
  433. _videoOutgoing->setState(Webrtc::VideoState::Inactive);
  434. } else if (state != Webrtc::VideoState::Inactive
  435. && _instance
  436. && !_instance->supportsVideo()) {
  437. _errors.fire({ ErrorType::NotVideoCall });
  438. _videoOutgoing->setState(Webrtc::VideoState::Inactive);
  439. } else if (state != Webrtc::VideoState::Inactive) {
  440. // Paused not supported right now.
  441. Assert(state == Webrtc::VideoState::Active);
  442. if (!_videoCapture) {
  443. _videoCapture = _delegate->callGetVideoCapture(
  444. _videoCaptureDeviceId,
  445. _videoCaptureIsScreencast);
  446. _videoCapture->setOutput(_videoOutgoing->sink());
  447. }
  448. _videoCapture->setState(tgcalls::VideoState::Active);
  449. if (_instance) {
  450. _instance->setVideoCapture(_videoCapture);
  451. }
  452. } else if (_videoCapture) {
  453. _videoCapture->setState(tgcalls::VideoState::Inactive);
  454. if (_instance) {
  455. _instance->setVideoCapture(nullptr);
  456. }
  457. }
  458. }, _lifetime);
  459. _cameraDeviceId.changes(
  460. ) | rpl::filter([=] {
  461. return !_videoCaptureIsScreencast;
  462. }) | rpl::start_with_next([=](Webrtc::DeviceResolvedId deviceId) {
  463. const auto &id = deviceId.value;
  464. _videoCaptureDeviceId = id;
  465. if (_videoCapture) {
  466. _videoCapture->switchToDevice(id.toStdString(), false);
  467. if (_instance) {
  468. _instance->sendVideoDeviceUpdated();
  469. }
  470. }
  471. }, _lifetime);
  472. }
  473. not_null<Webrtc::VideoTrack*> Call::videoIncoming() const {
  474. return _videoIncoming.get();
  475. }
  476. not_null<Webrtc::VideoTrack*> Call::videoOutgoing() const {
  477. return _videoOutgoing.get();
  478. }
  479. crl::time Call::getDurationMs() const {
  480. return _startTime ? (crl::now() - _startTime) : 0;
  481. }
  482. void Call::hangup() {
  483. const auto state = _state.current();
  484. if (state == State::Busy) {
  485. _delegate->callFinished(this);
  486. } else {
  487. const auto missed = (state == State::Ringing
  488. || (state == State::Waiting && _type == Type::Outgoing));
  489. const auto declined = isIncomingWaiting();
  490. const auto reason = missed
  491. ? MTP_phoneCallDiscardReasonMissed()
  492. : declined
  493. ? MTP_phoneCallDiscardReasonBusy()
  494. : MTP_phoneCallDiscardReasonHangup();
  495. finish(FinishType::Ended, reason);
  496. }
  497. }
  498. void Call::redial() {
  499. if (_state.current() != State::Busy) {
  500. return;
  501. }
  502. Assert(_instance == nullptr);
  503. _type = Type::Outgoing;
  504. setState(State::Requesting);
  505. _answerAfterDhConfigReceived = false;
  506. startWaitingTrack();
  507. _delegate->callRedial(this);
  508. }
  509. QString Call::getDebugLog() const {
  510. return _instance
  511. ? QString::fromStdString(_instance->getDebugInfo())
  512. : QString();
  513. }
  514. void Call::startWaitingTrack() {
  515. _waitingTrack = Media::Audio::Current().createTrack();
  516. const auto trackFileName = Core::App().settings().getSoundPath(
  517. (_type == Type::Outgoing)
  518. ? u"call_outgoing"_q
  519. : u"call_incoming"_q);
  520. _waitingTrack->samplePeakEach(kSoundSampleMs);
  521. _waitingTrack->fillFromFile(trackFileName);
  522. _waitingTrack->playInLoop();
  523. }
  524. void Call::sendSignalingData(const QByteArray &data) {
  525. _api.request(MTPphone_SendSignalingData(
  526. MTP_inputPhoneCall(
  527. MTP_long(_id),
  528. MTP_long(_accessHash)),
  529. MTP_bytes(data)
  530. )).done([=](const MTPBool &result) {
  531. if (!mtpIsTrue(result)) {
  532. finish(FinishType::Failed);
  533. }
  534. }).fail([=](const MTP::Error &error) {
  535. handleRequestError(error.type());
  536. }).send();
  537. }
  538. float64 Call::getWaitingSoundPeakValue() const {
  539. if (_waitingTrack) {
  540. const auto when = crl::now() + kSoundSampleMs / 4;
  541. return _waitingTrack->getPeakValue(when);
  542. }
  543. return 0.;
  544. }
  545. bool Call::isKeyShaForFingerprintReady() const {
  546. return (_keyFingerprint != 0);
  547. }
  548. bytes::vector Call::getKeyShaForFingerprint() const {
  549. Expects(isKeyShaForFingerprintReady());
  550. Expects(!_ga.empty());
  551. auto encryptedChatAuthKey = bytes::vector(
  552. _authKey.size() + _ga.size(),
  553. gsl::byte{});
  554. bytes::copy(
  555. gsl::make_span(encryptedChatAuthKey).subspan(0, _authKey.size()),
  556. _authKey);
  557. bytes::copy(
  558. gsl::make_span(encryptedChatAuthKey).subspan(
  559. _authKey.size(),
  560. _ga.size()),
  561. _ga);
  562. return openssl::Sha256(encryptedChatAuthKey);
  563. }
  564. bool Call::handleUpdate(const MTPPhoneCall &call) {
  565. switch (call.type()) {
  566. case mtpc_phoneCallRequested: {
  567. const auto &data = call.c_phoneCallRequested();
  568. if (_type != Type::Incoming
  569. || _id != 0
  570. || peerToUser(_user->id) != UserId(data.vadmin_id())) {
  571. Unexpected("phoneCallRequested call inside an existing call "
  572. "handleUpdate()");
  573. }
  574. if (_user->session().userId() != UserId(data.vparticipant_id())) {
  575. LOG(("Call Error: Wrong call participant_id %1, expected %2."
  576. ).arg(data.vparticipant_id().v
  577. ).arg(_user->session().userId().bare));
  578. finish(FinishType::Failed);
  579. return true;
  580. }
  581. _id = data.vid().v;
  582. _accessHash = data.vaccess_hash().v;
  583. const auto gaHashBytes = bytes::make_span(data.vg_a_hash().v);
  584. if (gaHashBytes.size() != kSha256Size) {
  585. LOG(("Call Error: Wrong g_a_hash size %1, expected %2."
  586. ).arg(gaHashBytes.size()
  587. ).arg(kSha256Size));
  588. finish(FinishType::Failed);
  589. return true;
  590. }
  591. _gaHash = bytes::make_vector(gaHashBytes);
  592. } return true;
  593. case mtpc_phoneCallEmpty: {
  594. const auto &data = call.c_phoneCallEmpty();
  595. if (data.vid().v != _id) {
  596. return false;
  597. }
  598. LOG(("Call Error: phoneCallEmpty received."));
  599. finish(FinishType::Failed);
  600. } return true;
  601. case mtpc_phoneCallWaiting: {
  602. const auto &data = call.c_phoneCallWaiting();
  603. if (data.vid().v != _id) {
  604. return false;
  605. }
  606. if (_type == Type::Outgoing
  607. && _state.current() == State::Waiting
  608. && data.vreceive_date().value_or_empty() != 0) {
  609. const auto &config = _user->session().serverConfig();
  610. _discardByTimeoutTimer.callOnce(config.callRingTimeoutMs);
  611. setState(State::Ringing);
  612. startWaitingTrack();
  613. }
  614. } return true;
  615. case mtpc_phoneCall: {
  616. const auto &data = call.c_phoneCall();
  617. if (data.vid().v != _id) {
  618. return false;
  619. }
  620. if (_type == Type::Incoming
  621. && _state.current() == State::ExchangingKeys
  622. && !_instance) {
  623. startConfirmedCall(data);
  624. }
  625. } return true;
  626. case mtpc_phoneCallDiscarded: {
  627. const auto &data = call.c_phoneCallDiscarded();
  628. if (data.vid().v != _id) {
  629. return false;
  630. }
  631. if (data.is_need_debug()) {
  632. const auto debugLog = _instance
  633. ? _instance->getDebugInfo()
  634. : std::string();
  635. if (!debugLog.empty()) {
  636. user()->session().api().request(MTPphone_SaveCallDebug(
  637. MTP_inputPhoneCall(
  638. MTP_long(_id),
  639. MTP_long(_accessHash)),
  640. MTP_dataJSON(MTP_string(debugLog))
  641. )).send();
  642. }
  643. }
  644. if (data.is_need_rating() && _id && _accessHash) {
  645. const auto window = Core::App().windowFor(
  646. Window::SeparateId(_user));
  647. const auto session = &_user->session();
  648. const auto callId = _id;
  649. const auto callAccessHash = _accessHash;
  650. auto owned = Box<Ui::RateCallBox>(
  651. Core::App().settings().sendSubmitWay());
  652. const auto box = window
  653. ? window->show(std::move(owned))
  654. : Ui::show(std::move(owned));
  655. const auto sender = box->lifetime().make_state<MTP::Sender>(
  656. &session->mtp());
  657. box->sends(
  658. ) | rpl::take(
  659. 1 // Instead of keeping requestId.
  660. ) | rpl::start_with_next([=](const Ui::RateCallBox::Result &r) {
  661. sender->request(MTPphone_SetCallRating(
  662. MTP_flags(0),
  663. MTP_inputPhoneCall(
  664. MTP_long(callId),
  665. MTP_long(callAccessHash)),
  666. MTP_int(r.rating),
  667. MTP_string(r.comment)
  668. )).done([=](const MTPUpdates &updates) {
  669. session->api().applyUpdates(updates);
  670. box->closeBox();
  671. }).fail([=] {
  672. box->closeBox();
  673. }).send();
  674. }, box->lifetime());
  675. }
  676. const auto reason = data.vreason();
  677. if (reason
  678. && reason->type() == mtpc_phoneCallDiscardReasonDisconnect) {
  679. LOG(("Call Info: Discarded with DISCONNECT reason."));
  680. }
  681. if (reason && reason->type() == mtpc_phoneCallDiscardReasonBusy) {
  682. setState(State::Busy);
  683. } else if (_type == Type::Outgoing
  684. || _state.current() == State::HangingUp) {
  685. setState(State::Ended);
  686. } else {
  687. setState(State::EndedByOtherDevice);
  688. }
  689. } return true;
  690. case mtpc_phoneCallAccepted: {
  691. const auto &data = call.c_phoneCallAccepted();
  692. if (data.vid().v != _id) {
  693. return false;
  694. }
  695. if (_type != Type::Outgoing) {
  696. LOG(("Call Error: "
  697. "Unexpected phoneCallAccepted for an incoming call."));
  698. finish(FinishType::Failed);
  699. } else if (checkCallFields(data)) {
  700. confirmAcceptedCall(data);
  701. }
  702. } return true;
  703. }
  704. Unexpected("phoneCall type inside an existing call handleUpdate()");
  705. }
  706. void Call::updateRemoteMediaState(
  707. tgcalls::AudioState audio,
  708. tgcalls::VideoState video) {
  709. _remoteAudioState = [&] {
  710. using From = tgcalls::AudioState;
  711. using To = RemoteAudioState;
  712. switch (audio) {
  713. case From::Active: return To::Active;
  714. case From::Muted: return To::Muted;
  715. }
  716. Unexpected("Audio state in remoteMediaStateUpdated.");
  717. }();
  718. _videoIncoming->setState([&] {
  719. using From = tgcalls::VideoState;
  720. using To = Webrtc::VideoState;
  721. switch (video) {
  722. case From::Inactive: return To::Inactive;
  723. case From::Paused: return To::Paused;
  724. case From::Active: return To::Active;
  725. }
  726. Unexpected("Video state in remoteMediaStateUpdated.");
  727. }());
  728. }
  729. bool Call::handleSignalingData(
  730. const MTPDupdatePhoneCallSignalingData &data) {
  731. if (data.vphone_call_id().v != _id || !_instance) {
  732. return false;
  733. }
  734. auto prepared = ranges::views::all(
  735. data.vdata().v
  736. ) | ranges::views::transform([](char byte) {
  737. return static_cast<uint8_t>(byte);
  738. }) | ranges::to_vector;
  739. _instance->receiveSignalingData(std::move(prepared));
  740. return true;
  741. }
  742. void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) {
  743. Expects(_type == Type::Outgoing);
  744. if (_state.current() == State::ExchangingKeys
  745. || _instance) {
  746. LOG(("Call Warning: Unexpected confirmAcceptedCall."));
  747. return;
  748. }
  749. const auto firstBytes = bytes::make_span(call.vg_b().v);
  750. const auto computedAuthKey = MTP::CreateAuthKey(
  751. firstBytes,
  752. _randomPower,
  753. _dhConfig.p);
  754. if (computedAuthKey.empty()) {
  755. LOG(("Call Error: Could not compute mod-exp final."));
  756. finish(FinishType::Failed);
  757. return;
  758. }
  759. MTP::AuthKey::FillData(_authKey, computedAuthKey);
  760. _keyFingerprint = ComputeFingerprint(_authKey);
  761. setState(State::ExchangingKeys);
  762. _api.request(MTPphone_ConfirmCall(
  763. MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)),
  764. MTP_bytes(_ga),
  765. MTP_long(_keyFingerprint),
  766. MTP_phoneCallProtocol(
  767. MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p
  768. | MTPDphoneCallProtocol::Flag::f_udp_reflector),
  769. MTP_int(kMinLayer),
  770. MTP_int(tgcalls::Meta::MaxLayer()),
  771. MTP_vector(CollectVersionsForApi()))
  772. )).done([=](const MTPphone_PhoneCall &result) {
  773. Expects(result.type() == mtpc_phone_phoneCall);
  774. const auto &call = result.c_phone_phoneCall();
  775. _user->session().data().processUsers(call.vusers());
  776. if (call.vphone_call().type() != mtpc_phoneCall) {
  777. LOG(("Call Error: Expected phoneCall in response to "
  778. "phone.confirmCall()"));
  779. finish(FinishType::Failed);
  780. return;
  781. }
  782. createAndStartController(call.vphone_call().c_phoneCall());
  783. }).fail([=](const MTP::Error &error) {
  784. handleRequestError(error.type());
  785. }).send();
  786. }
  787. void Call::startConfirmedCall(const MTPDphoneCall &call) {
  788. Expects(_type == Type::Incoming);
  789. const auto firstBytes = bytes::make_span(call.vg_a_or_b().v);
  790. if (_gaHash != openssl::Sha256(firstBytes)) {
  791. LOG(("Call Error: Wrong g_a hash received."));
  792. finish(FinishType::Failed);
  793. return;
  794. }
  795. _ga = bytes::vector(firstBytes.begin(), firstBytes.end());
  796. const auto computedAuthKey = MTP::CreateAuthKey(
  797. firstBytes,
  798. _randomPower,
  799. _dhConfig.p);
  800. if (computedAuthKey.empty()) {
  801. LOG(("Call Error: Could not compute mod-exp final."));
  802. finish(FinishType::Failed);
  803. return;
  804. }
  805. MTP::AuthKey::FillData(_authKey, computedAuthKey);
  806. _keyFingerprint = ComputeFingerprint(_authKey);
  807. createAndStartController(call);
  808. }
  809. void Call::createAndStartController(const MTPDphoneCall &call) {
  810. _discardByTimeoutTimer.cancel();
  811. if (!checkCallFields(call) || _authKey.size() != kAuthKeySize) {
  812. return;
  813. }
  814. const auto &protocol = call.vprotocol().c_phoneCallProtocol();
  815. const auto &serverConfig = _user->session().serverConfig();
  816. auto encryptionKeyValue = std::make_shared<std::array<
  817. uint8_t,
  818. kAuthKeySize>>();
  819. memcpy(encryptionKeyValue->data(), _authKey.data(), kAuthKeySize);
  820. const auto version = call.vprotocol().match([&](
  821. const MTPDphoneCallProtocol &data) {
  822. return data.vlibrary_versions().v;
  823. }).value(0, MTP_bytes(kDefaultVersion)).v;
  824. LOG(("Call Info: Creating instance with version '%1', allowP2P: %2").arg(
  825. QString::fromUtf8(version),
  826. Logs::b(call.is_p2p_allowed())));
  827. const auto versionString = version.toStdString();
  828. const auto &settings = Core::App().settings();
  829. const auto weak = base::make_weak(this);
  830. _setDeviceIdCallback = nullptr;
  831. const auto playbackDeviceIdInitial = _playbackDeviceId.current();
  832. const auto captureDeviceIdInitial = _captureDeviceId.current();
  833. const auto saveSetDeviceIdCallback = [=](
  834. Fn<void(Webrtc::DeviceResolvedId)> setDeviceIdCallback) {
  835. setDeviceIdCallback(playbackDeviceIdInitial);
  836. setDeviceIdCallback(captureDeviceIdInitial);
  837. crl::on_main(weak, [=] {
  838. _setDeviceIdCallback = std::move(setDeviceIdCallback);
  839. const auto playback = _playbackDeviceId.current();
  840. if (_instance && playback != playbackDeviceIdInitial) {
  841. _setDeviceIdCallback(playback);
  842. // Value doesn't matter here, just trigger reading of the...
  843. _instance->setAudioOutputDevice(
  844. playback.value.toStdString());
  845. }
  846. const auto capture = _captureDeviceId.current();
  847. if (_instance && capture != captureDeviceIdInitial) {
  848. _setDeviceIdCallback(capture);
  849. // Value doesn't matter here, just trigger reading of the...
  850. _instance->setAudioInputDevice(capture.value.toStdString());
  851. }
  852. });
  853. };
  854. tgcalls::Descriptor descriptor = {
  855. .version = versionString,
  856. .config = tgcalls::Config{
  857. .initializationTimeout
  858. = serverConfig.callConnectTimeoutMs / 1000.,
  859. .receiveTimeout = serverConfig.callPacketTimeoutMs / 1000.,
  860. .dataSaving = tgcalls::DataSaving::Never,
  861. .enableP2P = call.is_p2p_allowed(),
  862. .enableAEC = false,
  863. .enableNS = true,
  864. .enableAGC = true,
  865. .enableVolumeControl = true,
  866. .maxApiLayer = protocol.vmax_layer().v,
  867. },
  868. .encryptionKey = tgcalls::EncryptionKey(
  869. std::move(encryptionKeyValue),
  870. (_type == Type::Outgoing)),
  871. .mediaDevicesConfig = tgcalls::MediaDevicesConfig{
  872. .audioInputId = captureDeviceIdInitial.value.toStdString(),
  873. .audioOutputId = playbackDeviceIdInitial.value.toStdString(),
  874. .inputVolume = 1.f,//settings.callInputVolume() / 100.f,
  875. .outputVolume = 1.f,//settings.callOutputVolume() / 100.f,
  876. },
  877. .videoCapture = _videoCapture,
  878. .stateUpdated = [=](tgcalls::State state) {
  879. crl::on_main(weak, [=] {
  880. handleControllerStateChange(state);
  881. });
  882. },
  883. .signalBarsUpdated = [=](int count) {
  884. crl::on_main(weak, [=] {
  885. handleControllerBarCountChange(count);
  886. });
  887. },
  888. .remoteBatteryLevelIsLowUpdated = [=](bool isLow) {
  889. #ifdef _DEBUG
  890. // isLow = true;
  891. #endif
  892. crl::on_main(weak, [=] {
  893. _remoteBatteryState = isLow
  894. ? RemoteBatteryState::Low
  895. : RemoteBatteryState::Normal;
  896. });
  897. },
  898. .remoteMediaStateUpdated = [=](
  899. tgcalls::AudioState audio,
  900. tgcalls::VideoState video) {
  901. crl::on_main(weak, [=] {
  902. updateRemoteMediaState(audio, video);
  903. });
  904. },
  905. .signalingDataEmitted = [=](const std::vector<uint8_t> &data) {
  906. const auto bytes = QByteArray(
  907. reinterpret_cast<const char*>(data.data()),
  908. data.size());
  909. crl::on_main(weak, [=] {
  910. sendSignalingData(bytes);
  911. });
  912. },
  913. .createAudioDeviceModule = Webrtc::AudioDeviceModuleCreator(
  914. saveSetDeviceIdCallback),
  915. };
  916. if (Logs::DebugEnabled()) {
  917. const auto callLogFolder = cWorkingDir() + u"DebugLogs"_q;
  918. const auto callLogPath = callLogFolder + u"/last_call_log.txt"_q;
  919. const auto callLogNative = QDir::toNativeSeparators(callLogPath);
  920. #ifdef Q_OS_WIN
  921. descriptor.config.logPath.data = callLogNative.toStdWString();
  922. #else // Q_OS_WIN
  923. const auto callLogUtf = QFile::encodeName(callLogNative);
  924. descriptor.config.logPath.data.resize(callLogUtf.size());
  925. ranges::copy(callLogUtf, descriptor.config.logPath.data.begin());
  926. #endif // Q_OS_WIN
  927. QFile(callLogPath).remove();
  928. QDir().mkpath(callLogFolder);
  929. }
  930. const auto ids = CollectEndpointIds(call.vconnections().v);
  931. for (const auto &connection : call.vconnections().v) {
  932. AppendEndpoint(descriptor.endpoints, connection);
  933. }
  934. for (const auto &connection : call.vconnections().v) {
  935. AppendServer(descriptor.rtcServers, connection, ids);
  936. }
  937. {
  938. const auto &settingsProxy = Core::App().settings().proxy();
  939. using ProxyData = MTP::ProxyData;
  940. if (settingsProxy.useProxyForCalls() && settingsProxy.isEnabled()) {
  941. const auto &selected = settingsProxy.selected();
  942. if (selected.supportsCalls() && !selected.host.isEmpty()) {
  943. Assert(selected.type == ProxyData::Type::Socks5);
  944. descriptor.proxy = std::make_unique<tgcalls::Proxy>();
  945. descriptor.proxy->host = selected.host.toStdString();
  946. descriptor.proxy->port = selected.port;
  947. descriptor.proxy->login = selected.user.toStdString();
  948. descriptor.proxy->password = selected.password.toStdString();
  949. }
  950. }
  951. }
  952. _instance = tgcalls::Meta::Create(versionString, std::move(descriptor));
  953. if (!_instance) {
  954. LOG(("Call Error: Wrong library version: %1."
  955. ).arg(QString::fromUtf8(version)));
  956. finish(FinishType::Failed);
  957. return;
  958. }
  959. const auto raw = _instance.get();
  960. if (_muted.current()) {
  961. raw->setMuteMicrophone(_muted.current());
  962. }
  963. raw->setIncomingVideoOutput(_videoIncoming->sink());
  964. raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled());
  965. _state.value() | rpl::start_with_next([=](State state) {
  966. const auto track = (state != State::FailedHangingUp)
  967. && (state != State::Failed)
  968. && (state != State::HangingUp)
  969. && (state != State::Ended)
  970. && (state != State::EndedByOtherDevice)
  971. && (state != State::Busy);
  972. Core::App().mediaDevices().setCaptureMuteTracker(this, track);
  973. }, _instanceLifetime);
  974. _muted.value() | rpl::start_with_next([=](bool muted) {
  975. Core::App().mediaDevices().setCaptureMuted(muted);
  976. }, _instanceLifetime);
  977. #if 0
  978. Core::App().batterySaving().value(
  979. ) | rpl::start_with_next([=](bool isSaving) {
  980. crl::on_main(weak, [=] {
  981. if (_instance) {
  982. _instance->setIsLowBatteryLevel(isSaving);
  983. }
  984. });
  985. }, _instanceLifetime);
  986. #endif
  987. }
  988. void Call::handleControllerStateChange(tgcalls::State state) {
  989. switch (state) {
  990. case tgcalls::State::WaitInit: {
  991. DEBUG_LOG(("Call Info: State changed to WaitingInit."));
  992. setState(State::WaitingInit);
  993. } break;
  994. case tgcalls::State::WaitInitAck: {
  995. DEBUG_LOG(("Call Info: State changed to WaitingInitAck."));
  996. setState(State::WaitingInitAck);
  997. } break;
  998. case tgcalls::State::Established: {
  999. DEBUG_LOG(("Call Info: State changed to Established."));
  1000. setState(State::Established);
  1001. } break;
  1002. case tgcalls::State::Failed: {
  1003. const auto error = _instance
  1004. ? QString::fromStdString(_instance->getLastError())
  1005. : QString();
  1006. LOG(("Call Info: State changed to Failed, error: %1.").arg(error));
  1007. handleControllerError(error);
  1008. } break;
  1009. default: LOG(("Call Error: Unexpected state in handleStateChange: %1"
  1010. ).arg(int(state)));
  1011. }
  1012. }
  1013. void Call::handleControllerBarCountChange(int count) {
  1014. setSignalBarCount(count);
  1015. }
  1016. void Call::setSignalBarCount(int count) {
  1017. _signalBarCount = count;
  1018. }
  1019. template <typename T>
  1020. bool Call::checkCallCommonFields(const T &call) {
  1021. const auto checkFailed = [this] {
  1022. finish(FinishType::Failed);
  1023. return false;
  1024. };
  1025. if (call.vaccess_hash().v != _accessHash) {
  1026. LOG(("Call Error: Wrong call access_hash."));
  1027. return checkFailed();
  1028. }
  1029. const auto adminId = (_type == Type::Outgoing)
  1030. ? _user->session().userId()
  1031. : peerToUser(_user->id);
  1032. const auto participantId = (_type == Type::Outgoing)
  1033. ? peerToUser(_user->id)
  1034. : _user->session().userId();
  1035. if (UserId(call.vadmin_id()) != adminId) {
  1036. LOG(("Call Error: Wrong call admin_id %1, expected %2.")
  1037. .arg(call.vadmin_id().v)
  1038. .arg(adminId.bare));
  1039. return checkFailed();
  1040. }
  1041. if (UserId(call.vparticipant_id()) != participantId) {
  1042. LOG(("Call Error: Wrong call participant_id %1, expected %2.")
  1043. .arg(call.vparticipant_id().v)
  1044. .arg(participantId.bare));
  1045. return checkFailed();
  1046. }
  1047. return true;
  1048. }
  1049. bool Call::checkCallFields(const MTPDphoneCall &call) {
  1050. if (!checkCallCommonFields(call)) {
  1051. return false;
  1052. }
  1053. if (call.vkey_fingerprint().v != _keyFingerprint) {
  1054. LOG(("Call Error: Wrong call fingerprint."));
  1055. finish(FinishType::Failed);
  1056. return false;
  1057. }
  1058. return true;
  1059. }
  1060. bool Call::checkCallFields(const MTPDphoneCallAccepted &call) {
  1061. return checkCallCommonFields(call);
  1062. }
  1063. void Call::setState(State state) {
  1064. const auto was = _state.current();
  1065. if (was == State::Failed) {
  1066. return;
  1067. }
  1068. if (was == State::FailedHangingUp
  1069. && state != State::Failed) {
  1070. return;
  1071. }
  1072. if (was != state) {
  1073. _state = state;
  1074. if (true
  1075. && state != State::Starting
  1076. && state != State::Requesting
  1077. && state != State::Waiting
  1078. && state != State::WaitingIncoming
  1079. && state != State::Ringing) {
  1080. _waitingTrack.reset();
  1081. }
  1082. if (false
  1083. || state == State::Ended
  1084. || state == State::EndedByOtherDevice
  1085. || state == State::Failed
  1086. || state == State::Busy) {
  1087. // Destroy controller before destroying Call Panel,
  1088. // so that the panel hide animation is smooth.
  1089. destroyController();
  1090. }
  1091. switch (state) {
  1092. case State::Established:
  1093. _startTime = crl::now();
  1094. break;
  1095. case State::ExchangingKeys:
  1096. _delegate->callPlaySound(Delegate::CallSound::Connecting);
  1097. break;
  1098. case State::Ended:
  1099. if (was != State::WaitingUserConfirmation) {
  1100. _delegate->callPlaySound(Delegate::CallSound::Ended);
  1101. }
  1102. [[fallthrough]];
  1103. case State::EndedByOtherDevice:
  1104. _delegate->callFinished(this);
  1105. break;
  1106. case State::Failed:
  1107. _delegate->callPlaySound(Delegate::CallSound::Ended);
  1108. _delegate->callFailed(this);
  1109. break;
  1110. case State::Busy:
  1111. _delegate->callPlaySound(Delegate::CallSound::Busy);
  1112. _discardByTimeoutTimer.cancel();
  1113. break;
  1114. }
  1115. }
  1116. }
  1117. //void Call::setAudioVolume(bool input, float level) {
  1118. // if (_instance) {
  1119. // if (input) {
  1120. // _instance->setInputVolume(level);
  1121. // } else {
  1122. // _instance->setOutputVolume(level);
  1123. // }
  1124. // }
  1125. //}
  1126. void Call::setAudioDuckingEnabled(bool enabled) {
  1127. if (_instance) {
  1128. _instance->setAudioOutputDuckingEnabled(enabled);
  1129. }
  1130. }
  1131. bool Call::isSharingVideo() const {
  1132. return (_videoOutgoing->state() != Webrtc::VideoState::Inactive);
  1133. }
  1134. bool Call::isSharingCamera() const {
  1135. return !_videoCaptureIsScreencast && isSharingVideo();
  1136. }
  1137. bool Call::isSharingScreen() const {
  1138. return _videoCaptureIsScreencast && isSharingVideo();
  1139. }
  1140. QString Call::cameraSharingDeviceId() const {
  1141. return isSharingCamera() ? _videoCaptureDeviceId : QString();
  1142. }
  1143. QString Call::screenSharingDeviceId() const {
  1144. return isSharingScreen() ? _videoCaptureDeviceId : QString();
  1145. }
  1146. void Call::toggleCameraSharing(bool enabled) {
  1147. if (isSharingCamera() == enabled) {
  1148. return;
  1149. } else if (!enabled) {
  1150. if (_videoCapture) {
  1151. _videoCapture->setState(tgcalls::VideoState::Inactive);
  1152. }
  1153. _videoOutgoing->setState(Webrtc::VideoState::Inactive);
  1154. _videoCaptureDeviceId = QString();
  1155. return;
  1156. }
  1157. _delegate->callRequestPermissionsOrFail(crl::guard(this, [=] {
  1158. toggleScreenSharing(std::nullopt);
  1159. _videoCaptureDeviceId = _cameraDeviceId.current().value;
  1160. if (_videoCapture) {
  1161. _videoCapture->switchToDevice(
  1162. _videoCaptureDeviceId.toStdString(),
  1163. false);
  1164. if (_instance) {
  1165. _instance->sendVideoDeviceUpdated();
  1166. }
  1167. }
  1168. _videoOutgoing->setState(Webrtc::VideoState::Active);
  1169. }), true);
  1170. }
  1171. void Call::toggleScreenSharing(std::optional<QString> uniqueId) {
  1172. if (!uniqueId) {
  1173. if (isSharingScreen()) {
  1174. if (_videoCapture) {
  1175. _videoCapture->setState(tgcalls::VideoState::Inactive);
  1176. }
  1177. _videoOutgoing->setState(Webrtc::VideoState::Inactive);
  1178. }
  1179. _videoCaptureDeviceId = QString();
  1180. _videoCaptureIsScreencast = false;
  1181. return;
  1182. } else if (screenSharingDeviceId() == *uniqueId) {
  1183. return;
  1184. }
  1185. toggleCameraSharing(false);
  1186. _videoCaptureIsScreencast = true;
  1187. _videoCaptureDeviceId = *uniqueId;
  1188. if (_videoCapture) {
  1189. _videoCapture->switchToDevice(uniqueId->toStdString(), true);
  1190. if (_instance) {
  1191. _instance->sendVideoDeviceUpdated();
  1192. }
  1193. }
  1194. _videoOutgoing->setState(Webrtc::VideoState::Active);
  1195. }
  1196. auto Call::playbackDeviceIdValue() const
  1197. -> rpl::producer<Webrtc::DeviceResolvedId> {
  1198. return _playbackDeviceId.value();
  1199. }
  1200. rpl::producer<Webrtc::DeviceResolvedId> Call::captureDeviceIdValue() const {
  1201. return _captureDeviceId.value();
  1202. }
  1203. rpl::producer<Webrtc::DeviceResolvedId> Call::cameraDeviceIdValue() const {
  1204. return _cameraDeviceId.value();
  1205. }
  1206. void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) {
  1207. Expects(type != FinishType::None);
  1208. setSignalBarCount(kSignalBarFinished);
  1209. const auto finalState = (type == FinishType::Ended)
  1210. ? State::Ended
  1211. : State::Failed;
  1212. const auto hangupState = (type == FinishType::Ended)
  1213. ? State::HangingUp
  1214. : State::FailedHangingUp;
  1215. const auto state = _state.current();
  1216. if (state == State::Requesting) {
  1217. _finishByTimeoutTimer.call(kHangupTimeoutMs, [this, finalState] {
  1218. setState(finalState);
  1219. });
  1220. _finishAfterRequestingCall = type;
  1221. return;
  1222. }
  1223. if (state == State::HangingUp
  1224. || state == State::FailedHangingUp
  1225. || state == State::EndedByOtherDevice
  1226. || state == State::Ended
  1227. || state == State::Failed) {
  1228. return;
  1229. }
  1230. if (!_id) {
  1231. setState(finalState);
  1232. return;
  1233. }
  1234. setState(hangupState);
  1235. const auto duration = getDurationMs() / 1000;
  1236. const auto connectionId = _instance
  1237. ? _instance->getPreferredRelayId()
  1238. : 0;
  1239. _finishByTimeoutTimer.call(kHangupTimeoutMs, [this, finalState] {
  1240. setState(finalState);
  1241. });
  1242. using Video = Webrtc::VideoState;
  1243. const auto flags = ((_videoIncoming->state() != Video::Inactive)
  1244. || (_videoOutgoing->state() != Video::Inactive))
  1245. ? MTPphone_DiscardCall::Flag::f_video
  1246. : MTPphone_DiscardCall::Flag(0);
  1247. // We want to discard request still being sent and processed even if
  1248. // the call is already destroyed.
  1249. const auto session = &_user->session();
  1250. const auto weak = base::make_weak(this);
  1251. session->api().request(MTPphone_DiscardCall( // We send 'discard' here.
  1252. MTP_flags(flags),
  1253. MTP_inputPhoneCall(
  1254. MTP_long(_id),
  1255. MTP_long(_accessHash)),
  1256. MTP_int(duration),
  1257. reason,
  1258. MTP_long(connectionId)
  1259. )).done([=](const MTPUpdates &result) {
  1260. // Here 'this' could be destroyed by updates, so we set Ended after
  1261. // updates being handled, but in a guarded way.
  1262. crl::on_main(weak, [=] { setState(finalState); });
  1263. session->api().applyUpdates(result);
  1264. }).fail(crl::guard(weak, [this, finalState] {
  1265. setState(finalState);
  1266. })).send();
  1267. }
  1268. void Call::setStateQueued(State state) {
  1269. crl::on_main(this, [=] {
  1270. setState(state);
  1271. });
  1272. }
  1273. void Call::setFailedQueued(const QString &error) {
  1274. crl::on_main(this, [=] {
  1275. handleControllerError(error);
  1276. });
  1277. }
  1278. void Call::handleRequestError(const QString &error) {
  1279. const auto inform = (error == u"USER_PRIVACY_RESTRICTED"_q)
  1280. ? tr::lng_call_error_not_available(tr::now, lt_user, _user->name())
  1281. : (error == u"PARTICIPANT_VERSION_OUTDATED"_q)
  1282. ? tr::lng_call_error_outdated(tr::now, lt_user, _user->name())
  1283. : (error == u"CALL_PROTOCOL_LAYER_INVALID"_q)
  1284. ? Lang::Hard::CallErrorIncompatible().replace(
  1285. "{user}",
  1286. _user->name())
  1287. : QString();
  1288. if (!inform.isEmpty()) {
  1289. if (const auto window = Core::App().windowFor(
  1290. Window::SeparateId(_user))) {
  1291. window->show(Ui::MakeInformBox(inform));
  1292. } else {
  1293. Ui::show(Ui::MakeInformBox(inform));
  1294. }
  1295. }
  1296. finish(FinishType::Failed);
  1297. }
  1298. void Call::handleControllerError(const QString &error) {
  1299. const auto inform = (error == u"ERROR_INCOMPATIBLE"_q)
  1300. ? Lang::Hard::CallErrorIncompatible().replace(
  1301. "{user}",
  1302. _user->name())
  1303. : (error == u"ERROR_AUDIO_IO"_q)
  1304. ? tr::lng_call_error_audio_io(tr::now)
  1305. : QString();
  1306. if (!inform.isEmpty()) {
  1307. if (const auto window = Core::App().windowFor(
  1308. Window::SeparateId(_user))) {
  1309. window->show(Ui::MakeInformBox(inform));
  1310. } else {
  1311. Ui::show(Ui::MakeInformBox(inform));
  1312. }
  1313. }
  1314. finish(FinishType::Failed);
  1315. }
  1316. void Call::destroyController() {
  1317. _instanceLifetime.destroy();
  1318. Core::App().mediaDevices().setCaptureMuteTracker(this, false);
  1319. if (_instance) {
  1320. _instance->stop([](tgcalls::FinalState) {
  1321. });
  1322. DEBUG_LOG(("Call Info: Destroying call controller.."));
  1323. _instance.reset();
  1324. DEBUG_LOG(("Call Info: Call controller destroyed."));
  1325. }
  1326. setSignalBarCount(kSignalBarFinished);
  1327. }
  1328. Call::~Call() {
  1329. destroyController();
  1330. }
  1331. void UpdateConfig(const std::string &data) {
  1332. tgcalls::SetLegacyGlobalServerConfig(data);
  1333. }
  1334. } // namespace Calls