From a05940b705e9c381f26a77131b7c8ebf2c9cc5a8 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 8 May 2023 15:23:57 +0300 Subject: [PATCH] Make PrivacyManager an ordinary manager. --- SplitSource.php | 1 + td/telegram/PrivacyManager.cpp | 166 +++++++++++++++++++++------------ td/telegram/PrivacyManager.h | 28 +++--- td/telegram/Td.cpp | 14 +-- td/telegram/Td.h | 3 +- td/telegram/UpdatesManager.cpp | 2 +- 6 files changed, 132 insertions(+), 82 deletions(-) diff --git a/SplitSource.php b/SplitSource.php index b002bec95..bce654cf8 100644 --- a/SplitSource.php +++ b/SplitSource.php @@ -306,6 +306,7 @@ function split_file($file, $chunks, $undo) { 'option_manager[_(-][^.]|OptionManager' => "OptionManager", 'phone_number_manager[_(-][^.]|PhoneNumberManager' => "PhoneNumberManager", 'poll_manager[_(-][^.]|PollManager' => "PollManager", + 'privacy_manager[_(-][^.]|PrivacyManager' => "PrivacyManager", 'PublicDialogType|get_public_dialog_type' => 'PublicDialogType', 'SecretChatActor' => 'SecretChatActor', 'secret_chats_manager[_(-]|SecretChatsManager' => 'SecretChatsManager', diff --git a/td/telegram/PrivacyManager.cpp b/td/telegram/PrivacyManager.cpp index daa1b435d..28822c89c 100644 --- a/td/telegram/PrivacyManager.cpp +++ b/td/telegram/PrivacyManager.cpp @@ -14,6 +14,7 @@ #include "td/telegram/UserId.h" #include "td/utils/algorithm.h" +#include "td/utils/buffer.h" #include "td/utils/logging.h" #include @@ -21,6 +22,69 @@ namespace td { +class GetPrivacyQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetPrivacyQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserPrivacySetting user_privacy_setting) { + send_query(G()->net_query_creator().create( + telegram_api::account_getPrivacy(user_privacy_setting.get_input_privacy_key()))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetPrivacyQuery: " << to_string(ptr); + promise_.set_value(UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(ptr))); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class SetPrivacyQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit SetPrivacyQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules) { + send_query(G()->net_query_creator().create(telegram_api::account_setPrivacy( + user_privacy_setting.get_input_privacy_key(), privacy_rules.get_input_privacy_rules(td_)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SetPrivacyQuery: " << to_string(ptr); + promise_.set_value(UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(ptr))); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +PrivacyManager::PrivacyManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void PrivacyManager::tear_down() { + parent_.reset(); +} + void PrivacyManager::get_privacy(tl_object_ptr key, Promise> promise) { auto r_user_privacy_setting = UserPrivacySetting::get_user_privacy_setting(std::move(key)); @@ -30,72 +94,54 @@ void PrivacyManager::get_privacy(tl_object_ptr key, auto user_privacy_setting = r_user_privacy_setting.move_as_ok(); auto &info = get_info(user_privacy_setting); if (info.is_synchronized) { - return promise.set_value(info.rules.get_user_privacy_setting_rules_object(G()->td().get_actor_unsafe())); + return promise.set_value(info.rules.get_user_privacy_setting_rules_object(td_)); } info.get_promises.push_back(std::move(promise)); if (info.get_promises.size() > 1u) { // query has already been sent, just wait for the result return; } - auto net_query = - G()->net_query_creator().create(telegram_api::account_getPrivacy(user_privacy_setting.get_input_privacy_key())); - - send_with_promise(std::move(net_query), - PromiseCreator::lambda([this, user_privacy_setting](Result x_net_query) { - on_get_result(user_privacy_setting, [&]() -> Result { - TRY_RESULT(net_query, std::move(x_net_query)); - TRY_RESULT(rules, fetch_result(std::move(net_query))); - LOG(INFO) << "Receive " << to_string(rules); - return UserPrivacySettingRules::get_user_privacy_setting_rules(G()->td().get_actor_unsafe(), - std::move(rules)); - }()); - })); + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), user_privacy_setting](Result r_privacy_rules) { + send_closure(actor_id, &PrivacyManager::on_get_user_privacy_settings, user_privacy_setting, + std::move(r_privacy_rules)); + }); + td_->create_handler(std::move(query_promise))->send(user_privacy_setting); } void PrivacyManager::set_privacy(tl_object_ptr key, tl_object_ptr rules, Promise promise) { TRY_RESULT_PROMISE(promise, user_privacy_setting, UserPrivacySetting::get_user_privacy_setting(std::move(key))); - TRY_RESULT_PROMISE( - promise, privacy_rules, - UserPrivacySettingRules::get_user_privacy_setting_rules(G()->td().get_actor_unsafe(), std::move(rules))); + TRY_RESULT_PROMISE(promise, privacy_rules, + UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(rules))); auto &info = get_info(user_privacy_setting); if (info.has_set_query) { // TODO cancel previous query - return promise.set_error(Status::Error(400, "Another set_privacy query is active")); + return promise.set_error(Status::Error(400, "Another setUserPrivacySettingRules query is active")); } - auto net_query = G()->net_query_creator().create( - telegram_api::account_setPrivacy(user_privacy_setting.get_input_privacy_key(), - privacy_rules.get_input_privacy_rules(G()->td().get_actor_unsafe()))); - info.has_set_query = true; - send_with_promise( - std::move(net_query), PromiseCreator::lambda([this, user_privacy_setting, promise = std::move(promise)]( - Result x_net_query) mutable { - promise.set_result([&]() -> Result { - get_info(user_privacy_setting).has_set_query = false; - TRY_RESULT(net_query, std::move(x_net_query)); - TRY_RESULT(rules, fetch_result(std::move(net_query))); - LOG(INFO) << "Receive " << to_string(rules); - auto privacy_rules = - UserPrivacySettingRules::get_user_privacy_setting_rules(G()->td().get_actor_unsafe(), std::move(rules)); - do_update_privacy(user_privacy_setting, std::move(privacy_rules), true); - return Unit(); - }()); - })); + + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), user_privacy_setting, + promise = std::move(promise)](Result r_privacy_rules) mutable { + send_closure(actor_id, &PrivacyManager::on_set_user_privacy_settings, user_privacy_setting, + std::move(r_privacy_rules), std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(user_privacy_setting, std::move(privacy_rules)); } void PrivacyManager::on_update_privacy(tl_object_ptr update) { CHECK(update != nullptr); CHECK(update->key_ != nullptr); UserPrivacySetting user_privacy_setting(*update->key_); - auto privacy_rules = - UserPrivacySettingRules::get_user_privacy_setting_rules(G()->td().get_actor_unsafe(), std::move(update->rules_)); + auto privacy_rules = UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(update->rules_)); do_update_privacy(user_privacy_setting, std::move(privacy_rules), true); } -void PrivacyManager::on_get_result(UserPrivacySetting user_privacy_setting, - Result r_privacy_rules) { +void PrivacyManager::on_get_user_privacy_settings(UserPrivacySetting user_privacy_setting, + Result r_privacy_rules) { + G()->ignore_result_if_closing(r_privacy_rules); auto &info = get_info(user_privacy_setting); auto promises = std::move(info.get_promises); reset_to_empty(info.get_promises); @@ -103,7 +149,7 @@ void PrivacyManager::on_get_result(UserPrivacySetting user_privacy_setting, if (r_privacy_rules.is_error()) { promise.set_error(r_privacy_rules.error().clone()); } else { - promise.set_value(r_privacy_rules.ok().get_user_privacy_setting_rules_object(G()->td().get_actor_unsafe())); + promise.set_value(r_privacy_rules.ok().get_user_privacy_setting_rules_object(td_)); } } if (r_privacy_rules.is_ok()) { @@ -111,6 +157,20 @@ void PrivacyManager::on_get_result(UserPrivacySetting user_privacy_setting, } } +void PrivacyManager::on_set_user_privacy_settings(UserPrivacySetting user_privacy_setting, + Result r_privacy_rules, + Promise &&promise) { + G()->ignore_result_if_closing(r_privacy_rules); + auto &info = get_info(user_privacy_setting); + CHECK(info.has_set_query); + info.has_set_query = false; + if (r_privacy_rules.is_error()) { + return promise.set_error(r_privacy_rules.move_as_error()); + } + do_update_privacy(user_privacy_setting, r_privacy_rules.move_as_ok(), true); + promise.set_value(Unit()); +} + void PrivacyManager::do_update_privacy(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules, bool from_update) { auto &info = get_info(user_privacy_setting); @@ -147,27 +207,11 @@ void PrivacyManager::do_update_privacy(UserPrivacySetting user_privacy_setting, } info.rules = std::move(privacy_rules); - send_closure(G()->td(), &Td::send_update, - make_tl_object( - user_privacy_setting.get_user_privacy_setting_object(), - info.rules.get_user_privacy_setting_rules_object(G()->td().get_actor_unsafe()))); + send_closure( + G()->td(), &Td::send_update, + make_tl_object(user_privacy_setting.get_user_privacy_setting_object(), + info.rules.get_user_privacy_setting_rules_object(td_))); } } -void PrivacyManager::on_result(NetQueryPtr query) { - auto token = get_link_token(); - container_.extract(token).set_value(std::move(query)); -} - -void PrivacyManager::send_with_promise(NetQueryPtr query, Promise promise) { - auto id = container_.create(std::move(promise)); - G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, id)); -} - -void PrivacyManager::hangup() { - container_.for_each( - [](auto id, Promise &promise) { promise.set_error(Global::request_aborted_error()); }); - stop(); -} - } // namespace td diff --git a/td/telegram/PrivacyManager.h b/td/telegram/PrivacyManager.h index 1effacab1..83c2e47af 100644 --- a/td/telegram/PrivacyManager.h +++ b/td/telegram/PrivacyManager.h @@ -6,7 +6,6 @@ // #pragma once -#include "td/telegram/net/NetQuery.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserPrivacySetting.h" @@ -15,7 +14,6 @@ #include "td/actor/actor.h" #include "td/utils/common.h" -#include "td/utils/Container.h" #include "td/utils/Promise.h" #include "td/utils/Status.h" @@ -23,10 +21,11 @@ namespace td { -class PrivacyManager final : public NetQueryCallback { +class Td; + +class PrivacyManager final : public Actor { public: - explicit PrivacyManager(ActorShared<> parent) : parent_(std::move(parent)) { - } + PrivacyManager(Td *td, ActorShared<> parent); void get_privacy(tl_object_ptr key, Promise> promise); @@ -37,29 +36,32 @@ class PrivacyManager final : public NetQueryCallback { void on_update_privacy(tl_object_ptr update); private: - ActorShared<> parent_; - struct PrivacyInfo { UserPrivacySettingRules rules; vector>> get_promises; bool has_set_query = false; bool is_synchronized = false; }; - std::array(UserPrivacySetting::Type::Size)> info_; + + void tear_down() final; PrivacyInfo &get_info(UserPrivacySetting key) { return info_[static_cast(key.type())]; } - void on_get_result(UserPrivacySetting user_privacy_setting, Result r_privacy_rules); + void on_get_user_privacy_settings(UserPrivacySetting user_privacy_setting, + Result r_privacy_rules); + + void on_set_user_privacy_settings(UserPrivacySetting user_privacy_setting, + Result r_privacy_rules, Promise &&promise); + void do_update_privacy(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules, bool from_update); - void on_result(NetQueryPtr query) final; - Container> container_; - void send_with_promise(NetQueryPtr query, Promise promise); + std::array(UserPrivacySetting::Type::Size)> info_; - void hangup() final; + Td *td_; + ActorShared<> parent_; }; } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 59ee80f60..aaf0f8d73 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3239,6 +3239,8 @@ void Td::dec_actor_refcnt() { LOG(DEBUG) << "NotificationSettingsManager was cleared" << timer; poll_manager_.reset(); LOG(DEBUG) << "PollManager was cleared" << timer; + privacy_manager_.reset(); + LOG(DEBUG) << "PrivacyManager was cleared" << timer; sponsored_message_manager_.reset(); LOG(DEBUG) << "SponsoredMessageManager was cleared" << timer; stickers_manager_.reset(); @@ -3382,8 +3384,6 @@ void Td::clear() { LOG(DEBUG) << "NetStatsManager was cleared" << timer; password_manager_.reset(); LOG(DEBUG) << "PasswordManager was cleared" << timer; - privacy_manager_.reset(); - LOG(DEBUG) << "PrivacyManager was cleared" << timer; secure_manager_.reset(); LOG(DEBUG) << "SecureManager was cleared" << timer; secret_chats_manager_.reset(); @@ -3441,6 +3441,8 @@ void Td::clear() { LOG(DEBUG) << "NotificationSettingsManager actor was cleared" << timer; poll_manager_actor_.reset(); LOG(DEBUG) << "PollManager actor was cleared" << timer; + privacy_manager_actor_.reset(); + LOG(DEBUG) << "PrivacyManager actor was cleared" << timer; sponsored_message_manager_actor_.reset(); LOG(DEBUG) << "SponsoredMessageManager actor was cleared" << timer; stickers_manager_actor_.reset(); @@ -3930,6 +3932,8 @@ void Td::init_managers() { G()->set_notification_settings_manager(notification_settings_manager_actor_.get()); poll_manager_ = make_unique(this, create_reference()); poll_manager_actor_ = register_actor("PollManager", poll_manager_.get()); + privacy_manager_ = make_unique(this, create_reference()); + privacy_manager_actor_ = register_actor("PrivacyManager", privacy_manager_.get()); sponsored_message_manager_ = make_unique(this, create_reference()); sponsored_message_manager_actor_ = register_actor("SponsoredMessageManager", sponsored_message_manager_.get()); G()->set_sponsored_message_manager(sponsored_message_manager_actor_.get()); @@ -3969,7 +3973,6 @@ void Td::init_managers() { G()->set_language_pack_manager(language_pack_manager_.get()); password_manager_ = create_actor("PasswordManager", create_reference()); G()->set_password_manager(password_manager_.get()); - privacy_manager_ = create_actor("PrivacyManager", create_reference()); secure_manager_ = create_actor("SecureManager", create_reference()); verify_phone_number_manager_ = create_actor( "VerifyPhoneNumberManager", PhoneNumberManager::Type::VerifyPhone, create_reference()); @@ -4492,14 +4495,13 @@ void Td::on_request(uint64 id, td_api::registerDevice &request) { void Td::on_request(uint64 id, td_api::getUserPrivacySettingRules &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); - send_closure(privacy_manager_, &PrivacyManager::get_privacy, std::move(request.setting_), std::move(promise)); + privacy_manager_->get_privacy(std::move(request.setting_), std::move(promise)); } void Td::on_request(uint64 id, td_api::setUserPrivacySettingRules &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); - send_closure(privacy_manager_, &PrivacyManager::set_privacy, std::move(request.setting_), std::move(request.rules_), - std::move(promise)); + privacy_manager_->set_privacy(std::move(request.setting_), std::move(request.rules_), std::move(promise)); } void Td::on_request(uint64 id, const td_api::getDefaultMessageAutoDeleteTime &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 0350f25ad..5bba822a6 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -189,6 +189,8 @@ class Td final : public Actor { ActorOwn notification_settings_manager_actor_; unique_ptr poll_manager_; ActorOwn poll_manager_actor_; + unique_ptr privacy_manager_; + ActorOwn privacy_manager_actor_; unique_ptr sponsored_message_manager_; ActorOwn sponsored_message_manager_actor_; unique_ptr stickers_manager_; @@ -219,7 +221,6 @@ class Td final : public Actor { ActorOwn language_pack_manager_; ActorOwn net_stats_manager_; ActorOwn password_manager_; - ActorOwn privacy_manager_; ActorOwn secret_chats_manager_; ActorOwn secure_manager_; ActorOwn state_manager_; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 019447620..c3e5e2b9f 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -3932,7 +3932,7 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - send_closure(td_->privacy_manager_, &PrivacyManager::on_update_privacy, std::move(update)); + td_->privacy_manager_->on_update_privacy(std::move(update)); promise.set_value(Unit()); }