From 8485867fe010276f46c3c28f79bb3a1d24e6882b Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 2 May 2021 02:40:22 +0300 Subject: [PATCH] Add toggleGroupCallIsMyVideoEnabled. --- td/generate/scheme/td_api.tl | 10 ++- td/telegram/GroupCallManager.cpp | 116 +++++++++++++++++++++++++++++-- td/telegram/GroupCallManager.h | 13 +++- td/telegram/Td.cpp | 9 ++- td/telegram/Td.h | 2 + td/telegram/cli.cpp | 6 ++ 6 files changed, 146 insertions(+), 10 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index b84bf09fa..726690aac 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2162,12 +2162,13 @@ groupCallRecentSpeaker participant_id:MessageSender is_speaking:Bool = GroupCall //@participant_count Number of participants in the group call //@loaded_all_participants True, if all group call participants are loaded //@recent_speakers Recently speaking users in the group call +//@is_my_video_enabled True, if the current user's video is enabled //@can_start_video True, if video can be enabled by group call participants //@mute_new_participants True, if only group call administrators can unmute new participants //@can_change_mute_new_participants True, if the current user can enable or disable mute_new_participants setting //@record_duration Duration of the ongoing group call recording, in seconds; 0 if none. An updateGroupCall update is not triggered when value of this field changes, but the same recording goes on //@duration Call duration; for ended calls only -groupCall id:int32 title:string scheduled_start_date:int32 enabled_start_notification:Bool is_active:Bool is_joined:Bool need_rejoin:Bool can_be_managed:Bool participant_count:int32 loaded_all_participants:Bool recent_speakers:vector can_start_video:Bool mute_new_participants:Bool can_change_mute_new_participants:Bool record_duration:int32 duration:int32 = GroupCall; +groupCall id:int32 title:string scheduled_start_date:int32 enabled_start_notification:Bool is_active:Bool is_joined:Bool need_rejoin:Bool can_be_managed:Bool participant_count:int32 loaded_all_participants:Bool recent_speakers:vector is_my_video_enabled:Bool can_start_video:Bool mute_new_participants:Bool can_change_mute_new_participants:Bool record_duration:int32 duration:int32 = GroupCall; //@description Represents a group call participant @@ -4618,9 +4619,9 @@ toggleGroupCallEnabledStartNotification group_call_id:int32 enabled_start_notifi //@audio_source Caller audio synchronization source identifier; received from tgcalls //@payload Group call join payload; received from tgcalls //@is_muted True, if the user's microphone is muted -//@is_video_enabled True, if the user's video is enabled +//@is_my_video_enabled True, if the user's video is enabled //@invite_hash If non-empty, invite hash to be used to join the group call without being muted by administrators -joinGroupCall group_call_id:int32 participant_id:MessageSender audio_source:int32 payload:string is_muted:Bool is_video_enabled:Bool invite_hash:string = Text; +joinGroupCall group_call_id:int32 participant_id:MessageSender audio_source:int32 payload:string is_muted:Bool is_my_video_enabled:Bool invite_hash:string = Text; //@description Starts screen sharing in a joined group call. Returns join response payload for tgcalls @group_call_id Group call identifier @payload Group call join payload; received from tgcalls startGroupCallScreenSharing group_call_id:int32 payload:string = Text; @@ -4653,6 +4654,9 @@ startGroupCallRecording group_call_id:int32 title:string = Ok; //@description Ends recording of an active group call. Requires groupCall.can_be_managed group call flag @group_call_id Group call identifier endGroupCallRecording group_call_id:int32 = Ok; +//@description Toggles whether current user's video is enabled @group_call_id Group call identifier @is_my_video_enabled Pass true if the current user's video is enabled +toggleGroupCallIsMyVideoEnabled group_call_id:int32 is_my_video_enabled:Bool = Ok; + //@description Informs TDLib that speaking state of a participant of an active group has changed @group_call_id Group call identifier //@audio_source Group call participant's synchronization audio source identifier, or 0 for the current user @is_speaking True, if the user is speaking setGroupCallParticipantIsSpeaking group_call_id:int32 audio_source:int32 is_speaking:Bool = Ok; diff --git a/td/telegram/GroupCallManager.cpp b/td/telegram/GroupCallManager.cpp index b140b6573..2d45242fb 100644 --- a/td/telegram/GroupCallManager.cpp +++ b/td/telegram/GroupCallManager.cpp @@ -823,6 +823,7 @@ struct GroupCallManager::GroupCall { bool need_syncing_participants = false; bool loaded_all_participants = false; bool start_subscribed = false; + bool is_my_video_enabled = false; bool mute_new_participants = false; bool allowed_change_mute_new_participants = false; bool joined_date_asc = false; @@ -848,6 +849,8 @@ struct GroupCallManager::GroupCall { vector> after_join; bool have_pending_start_subscribed = false; bool pending_start_subscribed = false; + bool have_pending_is_my_video_enabled = false; + bool pending_is_my_video_enabled = false; bool have_pending_mute_new_participants = false; bool pending_mute_new_participants = false; string pending_title; @@ -1457,6 +1460,12 @@ bool GroupCallManager::get_group_call_start_subscribed(const GroupCall *group_ca : group_call->start_subscribed; } +bool GroupCallManager::get_group_call_is_my_video_enabled(const GroupCall *group_call) { + CHECK(group_call != nullptr); + return group_call->have_pending_is_my_video_enabled ? group_call->pending_is_my_video_enabled + : group_call->is_my_video_enabled; +} + bool GroupCallManager::get_group_call_mute_new_participants(const GroupCall *group_call) { CHECK(group_call != nullptr); return group_call->have_pending_mute_new_participants ? group_call->pending_mute_new_participants @@ -2365,7 +2374,7 @@ void GroupCallManager::start_scheduled_group_call(GroupCallId group_call_id, Pro } void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_dialog_id, int32 audio_source, - string &&payload, bool is_muted, bool is_video_enabled, + string &&payload, bool is_muted, bool is_my_video_enabled, const string &invite_hash, Promise &&promise) { TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id)); @@ -2431,7 +2440,7 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di }); request->query_ref = td_->create_handler(std::move(query_promise)) - ->send(input_group_call_id, as_dialog_id, payload, is_muted, !is_video_enabled, invite_hash, generation); + ->send(input_group_call_id, as_dialog_id, payload, is_muted, !is_my_video_enabled, invite_hash, generation); if (group_call->dialog_id.is_valid()) { td_->messages_manager_->on_update_dialog_default_join_group_call_as_dialog_id(group_call->dialog_id, as_dialog_id, @@ -2452,7 +2461,7 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di // it contains reasonable default "!call.mute_new_participants || call.can_be_managed" participant.server_is_muted_by_admin = !group_call->can_self_unmute && !can_manage_group_call(input_group_call_id); participant.server_is_muted_by_themselves = is_muted && !participant.server_is_muted_by_admin; - participant.server_is_video_muted = !is_video_enabled || participant.server_is_muted_by_admin; + participant.server_is_video_muted = !is_my_video_enabled || participant.server_is_muted_by_admin; participant.is_just_joined = !is_rejoin; participant.is_fake = true; int diff = process_group_call_participant(input_group_call_id, std::move(participant)); @@ -2462,6 +2471,10 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di set_group_call_participant_count(group_call, group_call->participant_count + diff, "join_group_call", true); } } + if (group_call->is_my_video_enabled != is_my_video_enabled) { + group_call->is_my_video_enabled = is_my_video_enabled; + need_update = true; + } if (group_call->is_inited && need_update) { send_update_group_call(group_call, "join_group_call"); @@ -2800,6 +2813,95 @@ void GroupCallManager::on_edit_group_call_title(InputGroupCallId input_group_cal } } +void GroupCallManager::toggle_group_call_is_my_video_enabled(GroupCallId group_call_id, bool is_my_video_enabled, + Promise &&promise) { + if (G()->close_flag()) { + return promise.set_error(Status::Error(500, "Request aborted")); + } + + TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id)); + + auto *group_call = get_group_call(input_group_call_id); + if (group_call == nullptr || !group_call->is_inited || !group_call->is_active) { + return promise.set_error(Status::Error(400, "GROUPCALL_JOIN_MISSING")); + } + if (!group_call->is_joined) { + if (is_group_call_being_joined(input_group_call_id) || group_call->need_rejoin) { + group_call->after_join.push_back( + PromiseCreator::lambda([actor_id = actor_id(this), group_call_id, is_my_video_enabled, + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(Status::Error(400, "GROUPCALL_JOIN_MISSING")); + } else { + send_closure(actor_id, &GroupCallManager::toggle_group_call_is_my_video_enabled, group_call_id, + is_my_video_enabled, std::move(promise)); + } + })); + return; + } + return promise.set_error(Status::Error(400, "GROUPCALL_JOIN_MISSING")); + } + + if (is_my_video_enabled == get_group_call_is_my_video_enabled(group_call)) { + return promise.set_value(Unit()); + } + + // there is no reason to save promise; we will send an update with actual value anyway + + group_call->pending_is_my_video_enabled = is_my_video_enabled; + if (!group_call->have_pending_is_my_video_enabled) { + group_call->have_pending_is_my_video_enabled = true; + send_toggle_group_call_is_my_video_enabled_query(input_group_call_id, group_call->as_dialog_id, + is_my_video_enabled); + } + send_update_group_call(group_call, "toggle_group_call_is_my_video_enabled"); + promise.set_value(Unit()); +} + +void GroupCallManager::send_toggle_group_call_is_my_video_enabled_query(InputGroupCallId input_group_call_id, + DialogId as_dialog_id, + bool is_my_video_enabled) { + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this), input_group_call_id, is_my_video_enabled](Result result) { + send_closure(actor_id, &GroupCallManager::on_toggle_group_call_is_my_video_enabled, input_group_call_id, + is_my_video_enabled, std::move(result)); + }); + td_->create_handler(std::move(promise)) + ->send(input_group_call_id, as_dialog_id, false, false, 0, false, false, true, !is_my_video_enabled); +} + +void GroupCallManager::on_toggle_group_call_is_my_video_enabled(InputGroupCallId input_group_call_id, + bool is_my_video_enabled, Result &&result) { + if (G()->close_flag()) { + return; + } + + auto *group_call = get_group_call(input_group_call_id); + if (group_call == nullptr || !group_call->is_inited || !group_call->is_active || + !group_call->have_pending_is_my_video_enabled) { + return; + } + + if (result.is_error()) { + group_call->have_pending_is_my_video_enabled = false; + LOG(ERROR) << "Failed to set is_my_video_enabled to " << is_my_video_enabled << " in " << input_group_call_id + << ": " << result.error(); + if (group_call->pending_is_my_video_enabled != group_call->is_my_video_enabled) { + send_update_group_call(group_call, "on_toggle_group_call_is_my_video_enabled failed"); + } + } else { + group_call->is_my_video_enabled = is_my_video_enabled; + if (group_call->pending_is_my_video_enabled != is_my_video_enabled) { + // need to send another request + send_toggle_group_call_is_my_video_enabled_query(input_group_call_id, group_call->as_dialog_id, + group_call->pending_is_my_video_enabled); + return; + } + + group_call->have_pending_is_my_video_enabled = false; + } +} + void GroupCallManager::toggle_group_call_start_subscribed(GroupCallId group_call_id, bool start_subscribed, Promise &&promise) { if (G()->close_flag()) { @@ -2838,7 +2940,7 @@ void GroupCallManager::toggle_group_call_start_subscribed(GroupCallId group_call group_call->have_pending_start_subscribed = true; send_toggle_group_call_start_subscription_query(input_group_call_id, start_subscribed); } - send_update_group_call(group_call, "toggle_group_call_start_subscription"); + send_update_group_call(group_call, "toggle_group_call_start_subscribed"); promise.set_value(Unit()); } @@ -3624,6 +3726,8 @@ void GroupCallManager::on_group_call_left_impl(GroupCall *group_call, bool need_ } group_call->is_being_left = false; group_call->is_speaking = false; + group_call->is_my_video_enabled = false; + group_call->have_pending_is_my_video_enabled = false; if (!group_call->is_active) { group_call->can_be_managed = false; } @@ -3808,6 +3912,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptrneed_rejoin; call.is_being_left = group_call->is_being_left; call.is_speaking = group_call->is_speaking; + call.is_my_video_enabled = group_call->is_my_video_enabled; call.syncing_participants = group_call->syncing_participants; call.need_syncing_participants = group_call->need_syncing_participants; call.loaded_all_participants = group_call->loaded_all_participants; @@ -4244,6 +4349,7 @@ tl_object_ptr GroupCallManager::get_group_call_object( bool is_active = scheduled_start_date == 0 ? group_call->is_active : 0; bool is_joined = group_call->is_joined && !group_call->is_being_left; bool start_subscribed = get_group_call_start_subscribed(group_call); + bool is_my_video_enabled = get_group_call_is_my_video_enabled(group_call); bool mute_new_participants = get_group_call_mute_new_participants(group_call); bool can_change_mute_new_participants = group_call->is_active && group_call->can_be_managed && group_call->allowed_change_mute_new_participants; @@ -4252,7 +4358,7 @@ tl_object_ptr GroupCallManager::get_group_call_object( return td_api::make_object( group_call->group_call_id.get(), get_group_call_title(group_call), scheduled_start_date, start_subscribed, is_active, is_joined, group_call->need_rejoin, group_call->can_be_managed, group_call->participant_count, - group_call->loaded_all_participants, std::move(recent_speakers), group_call->can_start_video, + group_call->loaded_all_participants, std::move(recent_speakers), is_my_video_enabled, group_call->can_start_video, mute_new_participants, can_change_mute_new_participants, record_duration, group_call->duration); } diff --git a/td/telegram/GroupCallManager.h b/td/telegram/GroupCallManager.h index 787bcd19f..63cb04aed 100644 --- a/td/telegram/GroupCallManager.h +++ b/td/telegram/GroupCallManager.h @@ -65,7 +65,7 @@ class GroupCallManager : public Actor { void start_scheduled_group_call(GroupCallId group_call_id, Promise &&promise); void join_group_call(GroupCallId group_call_id, DialogId as_dialog_id, int32 audio_source, string &&payload, - bool is_muted, bool is_video_enabled, const string &invite_hash, Promise &&promise); + bool is_muted, bool is_my_video_enabled, const string &invite_hash, Promise &&promise); void start_group_call_screen_sharing(GroupCallId group_call_id, string &&payload, Promise &&promise); @@ -73,6 +73,9 @@ class GroupCallManager : public Actor { void set_group_call_title(GroupCallId group_call_id, string title, Promise &&promise); + void toggle_group_call_is_my_video_enabled(GroupCallId group_call_id, bool is_my_video_enabled, + Promise &&promise); + void toggle_group_call_start_subscribed(GroupCallId group_call_id, bool start_subscribed, Promise &&promise); void toggle_group_call_mute_new_participants(GroupCallId group_call_id, bool mute_new_participants, @@ -193,6 +196,8 @@ class GroupCallManager : public Actor { static bool get_group_call_start_subscribed(const GroupCall *group_call); + static bool get_group_call_is_my_video_enabled(const GroupCall *group_call); + static bool get_group_call_mute_new_participants(const GroupCall *group_call); static int32 get_group_call_record_start_date(const GroupCall *group_call); @@ -260,6 +265,12 @@ class GroupCallManager : public Actor { void on_toggle_group_call_start_subscription(InputGroupCallId input_group_call_id, bool start_subscribed, Result &&result); + void send_toggle_group_call_is_my_video_enabled_query(InputGroupCallId input_group_call_id, DialogId as_dialog_id, + bool is_my_video_enabled); + + void on_toggle_group_call_is_my_video_enabled(InputGroupCallId input_group_call_id, bool is_my_video_enabled, + Result &&result); + void send_toggle_group_call_mute_new_participants_query(InputGroupCallId input_group_call_id, bool mute_new_participants); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 80fd1c8ba..8a4d75bee 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6032,7 +6032,7 @@ void Td::on_request(uint64 id, td_api::joinGroupCall &request) { group_call_manager_->join_group_call(GroupCallId(request.group_call_id_), group_call_manager_->get_group_call_participant_id(request.participant_id_), request.audio_source_, std::move(request.payload_), request.is_muted_, - request.is_video_enabled_, request.invite_hash_, std::move(query_promise)); + request.is_my_video_enabled_, request.invite_hash_, std::move(query_promise)); } void Td::on_request(uint64 id, td_api::startGroupCallScreenSharing &request) { @@ -6113,6 +6113,13 @@ void Td::on_request(uint64 id, const td_api::endGroupCallRecording &request) { std::move(promise)); } +void Td::on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoEnabled &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + group_call_manager_->toggle_group_call_is_my_video_enabled(GroupCallId(request.group_call_id_), + request.is_my_video_enabled_, std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 7dbc0a0cd..a36421d96 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -733,6 +733,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, const td_api::endGroupCallRecording &request); + void on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoEnabled &request); + void on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request); void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 0a3c7edfa..7233c459e 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2732,6 +2732,12 @@ class CliClient final : public Actor { td_api::make_object(as_group_call_id(args), op == "tgcmnpe")); } else if (op == "rgcil") { send_request(td_api::make_object(as_group_call_id(args))); + } else if (op == "tgcimve") { + string group_call_id; + bool is_my_video_enabled; + get_args(args, group_call_id, is_my_video_enabled); + send_request(td_api::make_object(as_group_call_id(group_call_id), + is_my_video_enabled)); } else if (op == "sgcpis") { string group_call_id; int32 source;