Save joined group call synchronization source.

This commit is contained in:
levlam 2020-12-04 01:56:27 +03:00
parent 803e6f20af
commit 49f7a56f11
7 changed files with 70 additions and 21 deletions

View File

@ -4348,11 +4348,11 @@ inviteGroupCallMembers group_call_id:int32 user_ids:vector<int32> = Ok;
//@group_call_id Group call identifier @user_id User identifier @is_muted Pass true if the user must be muted and false otherwise
toggleGroupCallMemberIsMuted group_call_id:int32 user_id:int32 is_muted:Bool = Ok;
//@description Checks group call source for validness. If the method returns an error with a message "GROUP_CALL_JOIN_MISSING", the call needs to be rejoined @group_call_id Group call identifier @source Caller synchronization source identifier
checkGroupCallSource group_call_id:int32 source:int32 = Ok;
//@description Checks whether a group call is still joined. Should be called after connection with the server has been lost. Returns an error with a message "GROUP_CALL_JOIN_MISSING" for non-joined calls @group_call_id Group call identifier
checkGroupCallIsJoined group_call_id:int32 = Ok;
//@description Leaves a group call @group_call_id Group call identifier @source Caller synchronization source identifier
leaveGroupCall group_call_id:int32 source:int32 = Ok;
//@description Leaves a group call @group_call_id Group call identifier
leaveGroupCall group_call_id:int32 = Ok;
//@description Discards a group call. Requires can_manage_calls rights in the corresponding chat @group_call_id Group call identifier
discardGroupCall group_call_id:int32 = Ok;

Binary file not shown.

View File

@ -333,16 +333,19 @@ struct GroupCallManager::GroupCall {
GroupCallId group_call_id;
bool is_inited = false;
bool is_active = false;
bool is_joined = false;
bool mute_new_members = false;
bool allowed_change_mute_new_members = false;
int32 member_count = 0;
int32 version = -1;
int32 duration = 0;
int32 source = 0;
};
struct GroupCallManager::PendingJoinRequest {
NetQueryRef query_ref;
uint64 generation = 0;
int32 source = 0;
Promise<td_api::object_ptr<td_api::groupCallJoinResponse>> promise;
};
@ -522,6 +525,7 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id,
auto &request = pending_join_requests_[input_group_call_id];
request = make_unique<PendingJoinRequest>();
request->generation = generation;
request->source = source;
request->promise = std::move(promise);
auto query_promise =
@ -625,6 +629,10 @@ void GroupCallManager::on_join_group_call_response(InputGroupCallId input_group_
LOG(ERROR) << "Failed to parse join response JSON object: " << result.error().message();
it->second->promise.set_error(Status::Error(500, "Receive invalid join group call response payload"));
} else {
auto group_call = get_group_call(input_group_call_id);
CHECK(group_call != nullptr);
group_call->is_joined = true;
group_call->source = it->second->source;
it->second->promise.set_value(result.move_as_ok());
}
pending_join_requests_.erase(it);
@ -685,14 +693,51 @@ void GroupCallManager::toggle_group_call_member_is_muted(GroupCallId group_call_
td_->create_handler<EditGroupCallMemberQuery>(std::move(promise))->send(input_group_call_id, user_id, is_muted);
}
void GroupCallManager::check_group_call_source(GroupCallId group_call_id, int32 source, Promise<Unit> &&promise) {
void GroupCallManager::check_group_call_is_joined(GroupCallId group_call_id, Promise<Unit> &&promise) {
TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id));
td_->create_handler<CheckGroupCallQuery>(std::move(promise))->send(input_group_call_id, source);
auto *group_call = get_group_call(input_group_call_id);
if (group_call == nullptr || !group_call->is_inited || !group_call->is_active || !group_call->is_joined) {
return promise.set_error(Status::Error(400, "GROUP_CALL_JOIN_MISSING"));
}
auto source = group_call->source;
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, source,
promise = std::move(promise)](Result<Unit> &&result) mutable {
if (result.is_error() && result.error().message() == "GROUP_CALL_JOIN_MISSING") {
send_closure(actor_id, &GroupCallManager::on_group_call_left, input_group_call_id, source);
}
promise.set_result(std::move(result));
});
td_->create_handler<CheckGroupCallQuery>(std::move(query_promise))->send(input_group_call_id, source);
}
void GroupCallManager::leave_group_call(GroupCallId group_call_id, int32 source, Promise<Unit> &&promise) {
void GroupCallManager::leave_group_call(GroupCallId group_call_id, Promise<Unit> &&promise) {
TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id));
td_->create_handler<LeaveGroupCallQuery>(std::move(promise))->send(input_group_call_id, source);
auto *group_call = get_group_call(input_group_call_id);
if (group_call == nullptr || !group_call->is_inited || !group_call->is_active || !group_call->is_joined) {
return promise.set_error(Status::Error(400, "GROUP_CALL_JOIN_MISSING"));
}
auto source = group_call->source;
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, source,
promise = std::move(promise)](Result<Unit> &&result) mutable {
if (result.is_ok()) {
send_closure(actor_id, &GroupCallManager::on_group_call_left, input_group_call_id, source);
}
promise.set_result(std::move(result));
});
td_->create_handler<LeaveGroupCallQuery>(std::move(query_promise))->send(input_group_call_id, source);
}
void GroupCallManager::on_group_call_left(InputGroupCallId input_group_call_id, int32 source) {
auto *group_call = get_group_call(input_group_call_id);
CHECK(group_call != nullptr && group_call->is_inited);
if (group_call->is_joined && group_call->source == source) {
group_call->is_joined = false;
group_call->source = 0;
}
}
void GroupCallManager::discard_group_call(GroupCallId group_call_id, Promise<Unit> &&promise) {
@ -715,6 +760,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptr<telegra
InputGroupCallId call_id;
GroupCall call;
call.is_inited = true;
string join_params;
switch (group_call_ptr->get_id()) {
case telegram_api::groupCall::ID: {
auto group_call = static_cast<const telegram_api::groupCall *>(group_call_ptr.get());
@ -725,7 +771,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptr<telegra
call.member_count = group_call->participants_count_;
call.version = group_call->version_;
if (group_call->params_ != nullptr) {
on_join_group_call_response(call_id, std::move(group_call->params_->data_));
join_params = std::move(group_call->params_->data_);
}
break;
}
@ -753,7 +799,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptr<telegra
if (!group_call->is_active) {
// never update ended calls
} else if (!call.is_active) {
// always update to an ended call
// always update to an ended call, droping also is_joined flag
*group_call = std::move(call);
need_update = true;
} else {
@ -772,10 +818,12 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptr<telegra
}
}
if (!join_params.empty()) {
on_join_group_call_response(call_id, std::move(join_params));
}
if (need_update) {
send_closure(G()->td(), &Td::send_update, get_update_group_call_object(group_call));
}
return call_id;
}

View File

@ -49,9 +49,9 @@ class GroupCallManager : public Actor {
void toggle_group_call_member_is_muted(GroupCallId group_call_id, UserId user_id, bool is_muted,
Promise<Unit> &&promise);
void check_group_call_source(GroupCallId group_call_id, int32 source, Promise<Unit> &&promise);
void check_group_call_is_joined(GroupCallId group_call_id, Promise<Unit> &&promise);
void leave_group_call(GroupCallId group_call_id, int32 source, Promise<Unit> &&promise);
void leave_group_call(GroupCallId group_call_id, Promise<Unit> &&promise);
void discard_group_call(GroupCallId group_call_id, Promise<Unit> &&promise);
@ -85,6 +85,8 @@ class GroupCallManager : public Actor {
void finish_join_group_call(InputGroupCallId input_group_call_id, uint64 generation, Status error);
void on_group_call_left(InputGroupCallId input_group_call_id, int32 source);
InputGroupCallId update_group_call(const tl_object_ptr<telegram_api::GroupCall> &group_call_ptr);
static Result<td_api::object_ptr<td_api::groupCallJoinResponse>> get_group_call_join_response_object(

View File

@ -6084,19 +6084,18 @@ void Td::on_request(uint64 id, const td_api::toggleGroupCallMemberIsMuted &reque
request.is_muted_, std::move(promise));
}
void Td::on_request(uint64 id, const td_api::checkGroupCallSource &request) {
void Td::on_request(uint64 id, const td_api::checkGroupCallIsJoined &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->check_group_call_source(GroupCallId(request.group_call_id_), request.source_,
std::move(promise));
group_call_manager_->check_group_call_is_joined(GroupCallId(request.group_call_id_), std::move(promise));
}
void Td::on_request(uint64 id, const td_api::leaveGroupCall &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
group_call_manager_->leave_group_call(GroupCallId(request.group_call_id_), request.source_, std::move(promise));
group_call_manager_->leave_group_call(GroupCallId(request.group_call_id_), std::move(promise));
}
void Td::on_request(uint64 id, const td_api::discardGroupCall &request) {

View File

@ -704,7 +704,7 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::toggleGroupCallMemberIsMuted &request);
void on_request(uint64 id, const td_api::checkGroupCallSource &request);
void on_request(uint64 id, const td_api::checkGroupCallIsJoined &request);
void on_request(uint64 id, const td_api::leaveGroupCall &request);

View File

@ -2867,10 +2867,10 @@ class CliClient final : public Actor {
std::tie(user_id, is_muted) = split(args);
send_request(td_api::make_object<td_api::toggleGroupCallMemberIsMuted>(as_group_call_id(group_call_id),
as_user_id(user_id), as_bool(is_muted)));
} else if (op == "cgcs") {
send_request(td_api::make_object<td_api::checkGroupCallSource>(as_group_call_id(args), 123));
} else if (op == "cgcij") {
send_request(td_api::make_object<td_api::checkGroupCallIsJoined>(as_group_call_id(args)));
} else if (op == "lgc") {
send_request(td_api::make_object<td_api::leaveGroupCall>(as_group_call_id(args), 123));
send_request(td_api::make_object<td_api::leaveGroupCall>(as_group_call_id(args)));
} else if (op == "dgc") {
send_request(td_api::make_object<td_api::discardGroupCall>(as_group_call_id(args)));
} else if (op == "gcil") {