451 lines
15 KiB
C++

//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/telegram/files/FileId.h"
#include "td/telegram/net/MtprotoHeader.h"
#include "td/telegram/net/NetQuery.h"
#include "td/telegram/net/NetQueryStats.h"
#include "td/telegram/td_api.h"
#include "td/telegram/TdCallback.h"
#include "td/telegram/TdDb.h"
#include "td/telegram/telegram_api.h"
#include "td/actor/actor.h"
#include "td/utils/buffer.h"
#include "td/utils/common.h"
#include "td/utils/Container.h"
#include "td/utils/FlatHashMap.h"
#include "td/utils/logging.h"
#include "td/utils/Promise.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
#include <memory>
#include <unordered_map>
#include <utility>
namespace td {
class AccountManager;
class AlarmManager;
class AnimationsManager;
class AttachMenuManager;
class AudiosManager;
class AuthManager;
class AutosaveManager;
class BackgroundManager;
class BoostManager;
class BotInfoManager;
class BusinessConnectionManager;
class BusinessManager;
class CallManager;
class CallbackQueriesManager;
class ChannelRecommendationManager;
class ChatManager;
class CommonDialogManager;
class ConfigManager;
class ConnectionStateManager;
class CountryInfoManager;
class DeviceTokenManager;
class DialogActionManager;
class DialogFilterManager;
class DialogInviteLinkManager;
class DialogManager;
class DialogParticipantManager;
class DocumentsManager;
class DownloadManager;
class FileManager;
class FileReferenceManager;
class ForumTopicManager;
class GameManager;
class GroupCallManager;
class InlineMessageManager;
class InlineQueriesManager;
class HashtagHints;
class LanguagePackManager;
class LinkManager;
class MessageImportManager;
class MessagesManager;
class NetStatsManager;
class NotificationManager;
class NotificationSettingsManager;
class OnlineManager;
class OptionManager;
class PasswordManager;
class PeopleNearbyManager;
class PhoneNumberManager;
class PollManager;
class PrivacyManager;
class PromoDataManager;
class QuickReplyManager;
class ReactionManager;
class Requests;
class SavedMessagesManager;
class SecureManager;
class SecretChatsManager;
class SponsoredMessageManager;
class StarManager;
class StateManager;
class StatisticsManager;
class StickersManager;
class StorageManager;
class StoryManager;
class TermsOfServiceManager;
class ThemeManager;
class TimeZoneManager;
class TopDialogManager;
class TranscriptionManager;
class TranslationManager;
class UpdatesManager;
class UserManager;
class VideoNotesManager;
class VideosManager;
class VoiceNotesManager;
class WebPagesManager;
extern int VERBOSITY_NAME(td_init);
extern int VERBOSITY_NAME(td_requests);
// Td may start closing after explicit "close" or "destroy" query.
// Or it may start closing by itself, because authorization is lost.
// It any case the parent will be notified via updateAuthorizationState.
//
// Td needs a way to know that it will receive no more queries.
// It happens after "hangup".
//
// Parent needs a way to know that it will receive no more updates.
// It happens after destruction of callback
class Td final : public Actor {
public:
Td(const Td &) = delete;
Td(Td &&) = delete;
Td &operator=(const Td &) = delete;
Td &operator=(Td &&) = delete;
~Td() final;
struct Options {
std::shared_ptr<NetQueryStats> net_query_stats;
};
Td(unique_ptr<TdCallback> callback, Options options);
void request(uint64 id, tl_object_ptr<td_api::Function> function);
void destroy();
void on_update(telegram_api::object_ptr<telegram_api::Updates> updates, uint64 auth_key_id);
void on_result(NetQueryPtr query);
bool can_ignore_background_updates() const {
return can_ignore_background_updates_;
}
bool ignore_background_updates() const;
unique_ptr<AudiosManager> audios_manager_;
unique_ptr<CallbackQueriesManager> callback_queries_manager_;
unique_ptr<DocumentsManager> documents_manager_;
unique_ptr<OptionManager> option_manager_;
unique_ptr<VideosManager> videos_manager_;
unique_ptr<AccountManager> account_manager_;
ActorOwn<AccountManager> account_manager_actor_;
unique_ptr<AnimationsManager> animations_manager_;
ActorOwn<AnimationsManager> animations_manager_actor_;
unique_ptr<AttachMenuManager> attach_menu_manager_;
ActorOwn<AttachMenuManager> attach_menu_manager_actor_;
unique_ptr<AuthManager> auth_manager_;
ActorOwn<AuthManager> auth_manager_actor_;
unique_ptr<AutosaveManager> autosave_manager_;
ActorOwn<AutosaveManager> autosave_manager_actor_;
unique_ptr<BackgroundManager> background_manager_;
ActorOwn<BackgroundManager> background_manager_actor_;
unique_ptr<BoostManager> boost_manager_;
ActorOwn<BoostManager> boost_manager_actor_;
unique_ptr<BotInfoManager> bot_info_manager_;
ActorOwn<BotInfoManager> bot_info_manager_actor_;
unique_ptr<BusinessConnectionManager> business_connection_manager_;
ActorOwn<BusinessConnectionManager> business_connection_manager_actor_;
unique_ptr<BusinessManager> business_manager_;
ActorOwn<BusinessManager> business_manager_actor_;
unique_ptr<ChannelRecommendationManager> channel_recommendation_manager_;
ActorOwn<ChannelRecommendationManager> channel_recommendation_manager_actor_;
unique_ptr<ChatManager> chat_manager_;
ActorOwn<ChatManager> chat_manager_actor_;
unique_ptr<CommonDialogManager> common_dialog_manager_;
ActorOwn<CommonDialogManager> common_dialog_manager_actor_;
unique_ptr<ConnectionStateManager> connection_state_manager_;
ActorOwn<ConnectionStateManager> connection_state_manager_actor_;
unique_ptr<CountryInfoManager> country_info_manager_;
ActorOwn<CountryInfoManager> country_info_manager_actor_;
unique_ptr<DialogActionManager> dialog_action_manager_;
ActorOwn<DialogActionManager> dialog_action_manager_actor_;
unique_ptr<DialogFilterManager> dialog_filter_manager_;
ActorOwn<DialogFilterManager> dialog_filter_manager_actor_;
unique_ptr<DialogInviteLinkManager> dialog_invite_link_manager_;
ActorOwn<DialogInviteLinkManager> dialog_invite_link_manager_actor_;
unique_ptr<DialogManager> dialog_manager_;
ActorOwn<DialogManager> dialog_manager_actor_;
unique_ptr<DialogParticipantManager> dialog_participant_manager_;
ActorOwn<DialogParticipantManager> dialog_participant_manager_actor_;
unique_ptr<DownloadManager> download_manager_;
ActorOwn<DownloadManager> download_manager_actor_;
unique_ptr<FileManager> file_manager_;
ActorOwn<FileManager> file_manager_actor_;
unique_ptr<FileReferenceManager> file_reference_manager_;
ActorOwn<FileReferenceManager> file_reference_manager_actor_;
unique_ptr<ForumTopicManager> forum_topic_manager_;
ActorOwn<ForumTopicManager> forum_topic_manager_actor_;
unique_ptr<GameManager> game_manager_;
ActorOwn<GameManager> game_manager_actor_;
unique_ptr<GroupCallManager> group_call_manager_;
ActorOwn<GroupCallManager> group_call_manager_actor_;
unique_ptr<InlineMessageManager> inline_message_manager_;
ActorOwn<InlineMessageManager> inline_message_manager_actor_;
unique_ptr<InlineQueriesManager> inline_queries_manager_;
ActorOwn<InlineQueriesManager> inline_queries_manager_actor_;
unique_ptr<LinkManager> link_manager_;
ActorOwn<LinkManager> link_manager_actor_;
unique_ptr<MessageImportManager> message_import_manager_;
ActorOwn<MessageImportManager> message_import_manager_actor_;
unique_ptr<MessagesManager> messages_manager_;
ActorOwn<MessagesManager> messages_manager_actor_;
unique_ptr<NotificationManager> notification_manager_;
ActorOwn<NotificationManager> notification_manager_actor_;
unique_ptr<NotificationSettingsManager> notification_settings_manager_;
ActorOwn<NotificationSettingsManager> notification_settings_manager_actor_;
unique_ptr<OnlineManager> online_manager_;
ActorOwn<OnlineManager> online_manager_actor_;
unique_ptr<PeopleNearbyManager> people_nearby_manager_;
ActorOwn<PeopleNearbyManager> people_nearby_manager_actor_;
unique_ptr<PhoneNumberManager> phone_number_manager_;
ActorOwn<PhoneNumberManager> phone_number_manager_actor_;
unique_ptr<PollManager> poll_manager_;
ActorOwn<PollManager> poll_manager_actor_;
unique_ptr<PrivacyManager> privacy_manager_;
ActorOwn<PrivacyManager> privacy_manager_actor_;
unique_ptr<PromoDataManager> promo_data_manager_;
ActorOwn<PromoDataManager> promo_data_manager_actor_;
unique_ptr<QuickReplyManager> quick_reply_manager_;
ActorOwn<QuickReplyManager> quick_reply_manager_actor_;
unique_ptr<ReactionManager> reaction_manager_;
ActorOwn<ReactionManager> reaction_manager_actor_;
unique_ptr<SavedMessagesManager> saved_messages_manager_;
ActorOwn<SavedMessagesManager> saved_messages_manager_actor_;
unique_ptr<SponsoredMessageManager> sponsored_message_manager_;
ActorOwn<SponsoredMessageManager> sponsored_message_manager_actor_;
unique_ptr<StarManager> star_manager_;
ActorOwn<StarManager> star_manager_actor_;
unique_ptr<StatisticsManager> statistics_manager_;
ActorOwn<StatisticsManager> statistics_manager_actor_;
unique_ptr<StickersManager> stickers_manager_;
ActorOwn<StickersManager> stickers_manager_actor_;
unique_ptr<StoryManager> story_manager_;
ActorOwn<StoryManager> story_manager_actor_;
unique_ptr<TermsOfServiceManager> terms_of_service_manager_;
ActorOwn<TermsOfServiceManager> terms_of_service_manager_actor_;
unique_ptr<ThemeManager> theme_manager_;
ActorOwn<ThemeManager> theme_manager_actor_;
unique_ptr<TimeZoneManager> time_zone_manager_;
ActorOwn<TimeZoneManager> time_zone_manager_actor_;
unique_ptr<TopDialogManager> top_dialog_manager_;
ActorOwn<TopDialogManager> top_dialog_manager_actor_;
unique_ptr<TranscriptionManager> transcription_manager_;
ActorOwn<TranscriptionManager> transcription_manager_actor_;
unique_ptr<TranslationManager> translation_manager_;
ActorOwn<TranslationManager> translation_manager_actor_;
unique_ptr<UpdatesManager> updates_manager_;
ActorOwn<UpdatesManager> updates_manager_actor_;
unique_ptr<UserManager> user_manager_;
ActorOwn<UserManager> user_manager_actor_;
unique_ptr<VideoNotesManager> video_notes_manager_;
ActorOwn<VideoNotesManager> video_notes_manager_actor_;
unique_ptr<VoiceNotesManager> voice_notes_manager_;
ActorOwn<VoiceNotesManager> voice_notes_manager_actor_;
unique_ptr<WebPagesManager> web_pages_manager_;
ActorOwn<WebPagesManager> web_pages_manager_actor_;
ActorOwn<AlarmManager> alarm_manager_;
ActorOwn<CallManager> call_manager_;
ActorOwn<HashtagHints> cashtag_search_hints_;
ActorOwn<ConfigManager> config_manager_;
ActorOwn<DeviceTokenManager> device_token_manager_;
ActorOwn<HashtagHints> hashtag_hints_;
ActorOwn<HashtagHints> hashtag_search_hints_;
ActorOwn<LanguagePackManager> language_pack_manager_;
ActorOwn<NetStatsManager> net_stats_manager_;
ActorOwn<PasswordManager> password_manager_;
ActorOwn<SecretChatsManager> secret_chats_manager_;
ActorOwn<SecureManager> secure_manager_;
ActorOwn<StateManager> state_manager_;
ActorOwn<StorageManager> storage_manager_;
class ResultHandler : public std::enable_shared_from_this<ResultHandler> {
public:
ResultHandler() = default;
ResultHandler(const ResultHandler &) = delete;
ResultHandler &operator=(const ResultHandler &) = delete;
virtual ~ResultHandler() = default;
virtual void on_result(BufferSlice packet) {
UNREACHABLE();
}
virtual void on_error(Status status) {
UNREACHABLE();
}
friend class Td;
protected:
void send_query(NetQueryPtr query);
Td *td_ = nullptr;
bool is_query_sent_ = false;
private:
void set_td(Td *td);
};
template <class HandlerT, class... Args>
std::shared_ptr<HandlerT> create_handler(Args &&...args) {
LOG_CHECK(close_flag_ < 2) << close_flag_
#if TD_CLANG || TD_GCC
<< ' ' << __PRETTY_FUNCTION__
#endif
;
auto ptr = std::make_shared<HandlerT>(std::forward<Args>(args)...);
ptr->set_td(this);
return ptr;
}
void send_update(tl_object_ptr<td_api::Update> &&object);
static td_api::object_ptr<td_api::Object> static_request(td_api::object_ptr<td_api::Function> function);
private:
void run_request(uint64 id, td_api::object_ptr<td_api::Function> function);
void send_result(uint64 id, tl_object_ptr<td_api::Object> object);
void send_error(uint64 id, Status error);
void send_error_impl(uint64 id, tl_object_ptr<td_api::error> error);
ActorShared<Td> create_reference();
void inc_actor_refcnt();
void dec_actor_refcnt();
void inc_request_actor_refcnt();
void dec_request_actor_refcnt();
void close();
void on_closed();
void dec_stop_cnt();
unique_ptr<TdCallback> callback_;
Options td_options_;
MtprotoHeader::Options options_;
unique_ptr<Requests> requests_;
std::unordered_multimap<uint64, int32> request_set_;
int actor_refcnt_ = 0;
int request_actor_refcnt_ = 0;
int stop_cnt_ = 2;
bool destroy_flag_ = false;
int close_flag_ = 0;
enum class State : int32 { WaitParameters, Run, Close } state_ = State::WaitParameters;
uint64 set_parameters_request_id_ = 0;
FlatHashMap<uint64, std::shared_ptr<ResultHandler>> result_handlers_;
enum : int8 { RequestActorIdType = 1, ActorIdType = 2 };
Container<ActorOwn<Actor>> request_actors_;
bool can_ignore_background_updates_ = false;
vector<std::pair<uint64, td_api::object_ptr<td_api::Function>>> pending_preauthentication_requests_;
vector<std::pair<uint64, td_api::object_ptr<td_api::Function>>> pending_set_parameters_requests_;
vector<std::pair<uint64, td_api::object_ptr<td_api::Function>>> pending_init_requests_;
template <class T>
void complete_pending_preauthentication_requests(const T &func);
td_api::object_ptr<td_api::AuthorizationState> get_fake_authorization_state_object() const;
vector<td_api::object_ptr<td_api::Update>> get_fake_current_state() const;
template <class T>
friend class RequestActor; // uses send_result/send_error
friend class AuthManager; // uses send_result/send_error, TODO pass Promise<>
friend class Requests;
void add_handler(uint64 id, std::shared_ptr<ResultHandler> handler);
std::shared_ptr<ResultHandler> extract_handler(uint64 id);
void clear_requests();
void on_file_download_finished(FileId file_id);
std::shared_ptr<ActorContext> old_context_;
static bool is_authentication_request(int32 id);
static bool is_preinitialization_request(int32 id);
static bool is_preauthentication_request(int32 id);
struct Parameters {
int32 api_id_ = 0;
string api_hash_;
bool use_secret_chats_ = false;
};
void finish_set_parameters();
void init(Parameters parameters, Result<TdDb::OpenedDatabase> r_opened_database);
void init_options_and_network();
void init_file_manager();
void init_non_actor_managers();
void init_managers();
void init_pure_actor_managers();
void process_binlog_events(TdDb::OpenedDatabase &&events);
void clear();
void close_impl(bool destroy_flag);
Result<std::pair<Parameters, TdDb::Parameters>> get_parameters(
td_api::object_ptr<td_api::setTdlibParameters> parameters) TD_WARN_UNUSED_RESULT;
static td_api::object_ptr<td_api::error> make_error(int32 code, CSlice error) {
return td_api::make_object<td_api::error>(code, error.str());
}
// Actor
void start_up() final;
void tear_down() final;
void hangup_shared() final;
void hangup() final;
};
} // namespace td