Support file reference repair for notification sounds.

This commit is contained in:
levlam 2022-04-15 16:27:30 +03:00
parent ff50eec3ee
commit 77532d67f8
5 changed files with 107 additions and 21 deletions

View File

@ -13,6 +13,7 @@
#include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileManager.h"
#include "td/telegram/Global.h" #include "td/telegram/Global.h"
#include "td/telegram/MessagesManager.h" #include "td/telegram/MessagesManager.h"
#include "td/telegram/NotificationSettingsManager.h"
#include "td/telegram/StickerSetId.h" #include "td/telegram/StickerSetId.h"
#include "td/telegram/StickersManager.h" #include "td/telegram/StickersManager.h"
#include "td/telegram/Td.h" #include "td/telegram/Td.h"
@ -60,6 +61,7 @@ fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // repa
fileSourceBasicGroupFull basic_group_id:int32 = FileSource; // repaired with messages.getFullChat fileSourceBasicGroupFull basic_group_id:int32 = FileSource; // repaired with messages.getFullChat
fileSourceSupergroupFull supergroup_id:int32 = FileSource; // repaired with messages.getFullChannel fileSourceSupergroupFull supergroup_id:int32 = FileSource; // repaired with messages.getFullChannel
fileSourceAppConfig = FileSource; // repaired with help.getAppConfig, not reliable fileSourceAppConfig = FileSource; // repaired with help.getAppConfig, not reliable
fileSourceSavedRingtones = FileSource; // repaired with account.getSavedRingtones
*/ */
FileSourceId FileReferenceManager::get_current_file_source_id() const { FileSourceId FileReferenceManager::get_current_file_source_id() const {
@ -131,6 +133,11 @@ bool FileReferenceManager::add_file_source(NodeId node_id, FileSourceId file_sou
return is_added; return is_added;
} }
FileSourceId FileReferenceManager::create_saved_ringtones_file_source() {
FileSourceSavedRingtones source;
return add_file_source_id(source, "saved notification sounds");
}
bool FileReferenceManager::remove_file_source(NodeId node_id, FileSourceId file_source_id) { bool FileReferenceManager::remove_file_source(NodeId node_id, FileSourceId file_source_id) {
CHECK(node_id.is_valid()); CHECK(node_id.is_valid());
bool is_removed = nodes_[node_id].file_source_ids.remove(file_source_id); bool is_removed = nodes_[node_id].file_source_ids.remove(file_source_id);
@ -305,6 +312,10 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source
}, },
[&](const FileSourceAppConfig &source) { [&](const FileSourceAppConfig &source) {
send_closure_later(G()->config_manager(), &ConfigManager::reget_app_config, std::move(promise)); send_closure_later(G()->config_manager(), &ConfigManager::reget_app_config, std::move(promise));
},
[&](const FileSourceSavedRingtones &source) {
send_closure_later(G()->notification_settings_manager(), &NotificationSettingsManager::repair_saved_ringtones,
std::move(promise));
})); }));
} }

View File

@ -52,6 +52,7 @@ class FileReferenceManager final : public Actor {
FileSourceId create_chat_full_file_source(ChatId chat_id); FileSourceId create_chat_full_file_source(ChatId chat_id);
FileSourceId create_channel_full_file_source(ChannelId channel_id); FileSourceId create_channel_full_file_source(ChannelId channel_id);
FileSourceId create_app_config_file_source(); FileSourceId create_app_config_file_source();
FileSourceId create_saved_ringtones_file_source();
using NodeId = FileId; using NodeId = FileId;
void repair_file_reference(NodeId node_id, Promise<> promise); void repair_file_reference(NodeId node_id, Promise<> promise);
@ -144,12 +145,15 @@ class FileReferenceManager final : public Actor {
struct FileSourceAppConfig { struct FileSourceAppConfig {
// empty // empty
}; };
struct FileSourceSavedRingtones {
// empty
};
// append only // append only
using FileSource = using FileSource = Variant<FileSourceMessage, FileSourceUserPhoto, FileSourceChatPhoto, FileSourceChannelPhoto,
Variant<FileSourceMessage, FileSourceUserPhoto, FileSourceChatPhoto, FileSourceChannelPhoto, FileSourceWallpapers, FileSourceWallpapers, FileSourceWebPage, FileSourceSavedAnimations,
FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers, FileSourceRecentStickers, FileSourceFavoriteStickers, FileSourceBackground,
FileSourceBackground, FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig>; FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig, FileSourceSavedRingtones>;
vector<FileSource> file_sources_; vector<FileSource> file_sources_;
int64 query_generation_{0}; int64 query_generation_{0};

View File

@ -15,6 +15,7 @@
#include "td/telegram/files/FileSourceId.h" #include "td/telegram/files/FileSourceId.h"
#include "td/telegram/FullMessageId.h" #include "td/telegram/FullMessageId.h"
#include "td/telegram/MessagesManager.h" #include "td/telegram/MessagesManager.h"
#include "td/telegram/NotificationSettingsManager.h"
#include "td/telegram/StickersManager.h" #include "td/telegram/StickersManager.h"
#include "td/telegram/Td.h" #include "td/telegram/Td.h"
#include "td/telegram/UserId.h" #include "td/telegram/UserId.h"
@ -50,7 +51,7 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer
}, },
[&](const FileSourceChatFull &source) { td::store(source.chat_id, storer); }, [&](const FileSourceChatFull &source) { td::store(source.chat_id, storer); },
[&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); }, [&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); },
[&](const FileSourceAppConfig &source) {})); [&](const FileSourceAppConfig &source) {}, [&](const FileSourceSavedRingtones &source) {}));
} }
template <class ParserT> template <class ParserT>
@ -114,6 +115,8 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) {
} }
case 12: case 12:
return td->stickers_manager_->get_app_config_file_source_id(); return td->stickers_manager_->get_app_config_file_source_id();
case 13:
return td->notification_settings_manager_->get_saved_ringtones_file_source_id();
default: default:
parser.set_error("Invalid type in FileSource"); parser.set_error("Invalid type in FileSource");
return FileSourceId(); return FileSourceId();

View File

@ -53,7 +53,7 @@ class UploadRingtoneQuery final : public Td::ResultHandler {
file_id_ = file_id; file_id_ = file_id;
send_query(G()->net_query_creator().create( send_query(G()->net_query_creator().create(
telegram_api::account_uploadRingtone(std::move(input_file), file_name, mime_type))); telegram_api::account_uploadRingtone(std::move(input_file), file_name, mime_type), {{"ringtone"}}));
} }
void on_result(BufferSlice packet) final { void on_result(BufferSlice packet) final {
@ -1052,6 +1052,7 @@ void NotificationSettingsManager::on_remove_saved_ringtone(int64 ringtone_id, Pr
CHECK(file_view.has_remote_location()); CHECK(file_view.has_remote_location());
if (file_view.remote_location().get_id() == ringtone_id) { if (file_view.remote_location().get_id() == ringtone_id) {
saved_ringtone_file_ids_.erase(it); saved_ringtone_file_ids_.erase(it);
on_saved_ringtones_updated(false);
break; break;
} }
} }
@ -1078,38 +1079,64 @@ Result<FileId> NotificationSettingsManager::get_ringtone(
void NotificationSettingsManager::reload_saved_ringtones(Promise<Unit> &&promise) { void NotificationSettingsManager::reload_saved_ringtones(Promise<Unit> &&promise) {
if (!is_active()) { if (!is_active()) {
return; return promise.set_error(Status::Error(400, "Don't need to reload saved notification sounds"));
} }
reload_saved_ringtone_queries_.push_back(std::move(promise)); reload_saved_ringtones_queries_.push_back(std::move(promise));
if (reload_saved_ringtone_queries_.size() == 1) { if (reload_saved_ringtones_queries_.size() == 1) {
auto query_promise = PromiseCreator::lambda( auto query_promise = PromiseCreator::lambda(
[actor_id = actor_id(this)](Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) { [actor_id = actor_id(this)](Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, std::move(result)); send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, false, std::move(result));
}); });
td_->create_handler<GetSavedRingtonesQuery>(std::move(query_promise))->send(saved_ringtone_hash_); td_->create_handler<GetSavedRingtonesQuery>(std::move(query_promise))->send(saved_ringtone_hash_);
} }
} }
void NotificationSettingsManager::repair_saved_ringtones(Promise<Unit> &&promise) {
if (!is_active()) {
return promise.set_error(Status::Error(400, "Don't need to repair saved notification sounds"));
}
repair_saved_ringtones_queries_.push_back(std::move(promise));
if (repair_saved_ringtones_queries_.size() == 1u) {
auto query_promise = PromiseCreator::lambda(
[actor_id = actor_id(this)](Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
send_closure(actor_id, &NotificationSettingsManager::on_reload_saved_ringtones, true, std::move(result));
});
td_->create_handler<GetSavedRingtonesQuery>(std::move(query_promise))->send(0);
}
}
void NotificationSettingsManager::on_reload_saved_ringtones( void NotificationSettingsManager::on_reload_saved_ringtones(
Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) { bool is_repair, Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result) {
if (!is_active()) { if (!is_active()) {
are_saved_ringtones_loaded_ = true; are_saved_ringtones_loaded_ = true;
set_promises(reload_saved_ringtone_queries_); set_promises(reload_saved_ringtones_queries_);
set_promises(repair_saved_ringtones_queries_);
return; return;
} }
if (result.is_error()) { if (result.is_error()) {
fail_promises(reload_saved_ringtone_queries_, result.move_as_error()); if (is_repair) {
set_timeout_in(Random::fast(60, 120)); fail_promises(repair_saved_ringtones_queries_, result.move_as_error());
} else {
fail_promises(reload_saved_ringtones_queries_, result.move_as_error());
set_timeout_in(Random::fast(60, 120));
}
return; return;
} }
set_timeout_in(Random::fast(3600, 4800)); if (!is_repair) {
set_timeout_in(Random::fast(3600, 4800));
}
auto saved_ringtones_ptr = result.move_as_ok(); auto saved_ringtones_ptr = result.move_as_ok();
auto constructor_id = saved_ringtones_ptr->get_id(); auto constructor_id = saved_ringtones_ptr->get_id();
if (constructor_id == telegram_api::account_savedRingtonesNotModified::ID) { if (constructor_id == telegram_api::account_savedRingtonesNotModified::ID) {
are_saved_ringtones_loaded_ = true; if (is_repair) {
set_promises(reload_saved_ringtone_queries_); fail_promises(repair_saved_ringtones_queries_, Status::Error(500, "Failed to repair saved animations"));
} else {
are_saved_ringtones_loaded_ = true;
set_promises(reload_saved_ringtones_queries_);
}
return; return;
} }
CHECK(constructor_id == telegram_api::account_savedRingtones::ID); CHECK(constructor_id == telegram_api::account_savedRingtones::ID);
@ -1130,12 +1157,42 @@ void NotificationSettingsManager::on_reload_saved_ringtones(
} }
bool need_update = new_saved_ringtone_file_ids != saved_ringtone_file_ids_; bool need_update = new_saved_ringtone_file_ids != saved_ringtone_file_ids_;
are_saved_ringtones_loaded_ = true;
if (need_update || saved_ringtone_hash_ != new_hash) { if (need_update || saved_ringtone_hash_ != new_hash) {
saved_ringtone_hash_ = new_hash; saved_ringtone_hash_ = new_hash;
saved_ringtone_file_ids_ = std::move(new_saved_ringtone_file_ids); saved_ringtone_file_ids_ = std::move(new_saved_ringtone_file_ids);
if (need_update) {
on_saved_ringtones_updated(false);
}
} }
are_saved_ringtones_loaded_ = true; if (is_repair) {
set_promises(reload_saved_ringtone_queries_); set_promises(repair_saved_ringtones_queries_);
} else {
set_promises(reload_saved_ringtones_queries_);
}
}
void NotificationSettingsManager::on_saved_ringtones_updated(bool from_database) {
CHECK(are_saved_ringtones_loaded_);
vector<FileId> new_sorted_saved_ringtone_file_ids = saved_ringtone_file_ids_;
std::sort(new_sorted_saved_ringtone_file_ids.begin(), new_sorted_saved_ringtone_file_ids.end());
if (new_sorted_saved_ringtone_file_ids != sorted_saved_ringtone_file_ids_) {
td_->file_manager_->change_files_source(get_saved_ringtones_file_source_id(), sorted_saved_ringtone_file_ids_,
new_sorted_saved_ringtone_file_ids);
sorted_saved_ringtone_file_ids_ = std::move(new_sorted_saved_ringtone_file_ids);
}
if (!from_database) {
// save_saved_ringtones_to_database();
}
}
FileSourceId NotificationSettingsManager::get_saved_ringtones_file_source_id() {
if (!saved_ringtones_file_source_id_.is_valid()) {
saved_ringtones_file_source_id_ = td_->file_reference_manager_->create_saved_ringtones_file_source();
}
return saved_ringtones_file_source_id_;
} }
void NotificationSettingsManager::send_get_dialog_notification_settings_query(DialogId dialog_id, void NotificationSettingsManager::send_get_dialog_notification_settings_query(DialogId dialog_id,

View File

@ -8,6 +8,7 @@
#include "td/telegram/DialogId.h" #include "td/telegram/DialogId.h"
#include "td/telegram/files/FileId.h" #include "td/telegram/files/FileId.h"
#include "td/telegram/files/FileSourceId.h"
#include "td/telegram/NotificationSettings.h" #include "td/telegram/NotificationSettings.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.h"
@ -59,6 +60,10 @@ class NotificationSettingsManager final : public Actor {
void reload_saved_ringtones(Promise<Unit> &&promise); void reload_saved_ringtones(Promise<Unit> &&promise);
void repair_saved_ringtones(Promise<Unit> &&promise);
FileSourceId get_saved_ringtones_file_source_id();
void send_save_ringtone_query(FileId ringtone_file_id, bool unsave, void send_save_ringtone_query(FileId ringtone_file_id, bool unsave,
Promise<telegram_api::object_ptr<telegram_api::account_SavedRingtone>> &&promise); Promise<telegram_api::object_ptr<telegram_api::account_SavedRingtone>> &&promise);
@ -125,7 +130,10 @@ class NotificationSettingsManager final : public Actor {
void on_remove_saved_ringtone(int64 ringtone_id, Promise<Unit> &&promise); void on_remove_saved_ringtone(int64 ringtone_id, Promise<Unit> &&promise);
void on_reload_saved_ringtones(Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result); void on_reload_saved_ringtones(bool is_repair,
Result<telegram_api::object_ptr<telegram_api::account_SavedRingtones>> &&result);
void on_saved_ringtones_updated(bool from_database);
ScopeNotificationSettings *get_scope_notification_settings(NotificationSettingsScope scope); ScopeNotificationSettings *get_scope_notification_settings(NotificationSettingsScope scope);
@ -167,6 +175,8 @@ class NotificationSettingsManager final : public Actor {
int64 saved_ringtone_hash_ = 0; int64 saved_ringtone_hash_ = 0;
vector<FileId> saved_ringtone_file_ids_; vector<FileId> saved_ringtone_file_ids_;
vector<FileId> sorted_saved_ringtone_file_ids_;
FileSourceId saved_ringtones_file_source_id_;
std::shared_ptr<UploadRingtoneCallback> upload_ringtone_callback_; std::shared_ptr<UploadRingtoneCallback> upload_ringtone_callback_;
@ -180,7 +190,8 @@ class NotificationSettingsManager final : public Actor {
}; };
FlatHashMap<FileId, UploadedRingtone, FileIdHash> being_uploaded_ringtones_; FlatHashMap<FileId, UploadedRingtone, FileIdHash> being_uploaded_ringtones_;
vector<Promise<Unit>> reload_saved_ringtone_queries_; vector<Promise<Unit>> reload_saved_ringtones_queries_;
vector<Promise<Unit>> repair_saved_ringtones_queries_;
FlatHashMap<DialogId, vector<Promise<Unit>>, DialogIdHash> get_dialog_notification_settings_queries_; FlatHashMap<DialogId, vector<Promise<Unit>>, DialogIdHash> get_dialog_notification_settings_queries_;
}; };