mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-26 02:20:46 +00:00
Fixed crash on incoming peer calls.
This commit is contained in:
parent
6ae15ff264
commit
6f3dbc4305
@ -259,7 +259,7 @@ private:
|
||||
const not_null<UserData*> _user;
|
||||
MTP::Sender _api;
|
||||
Type _type = Type::Outgoing;
|
||||
rpl::variable<State> _state = State::WaitingUserConfirmation;
|
||||
rpl::variable<State> _state = State::Starting;
|
||||
rpl::variable<RemoteAudioState> _remoteAudioState =
|
||||
RemoteAudioState::Active;
|
||||
rpl::variable<Webrtc::VideoState> _remoteVideoState;
|
||||
|
@ -324,31 +324,52 @@ void Instance::destroyCall(not_null<Call*> call) {
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::createCall(not_null<UserData*> user, Call::Type type, bool video) {
|
||||
auto call = std::make_unique<Call>(_delegate.get(), user, type, video);
|
||||
const auto raw = call.get();
|
||||
void Instance::createCall(
|
||||
not_null<UserData*> user,
|
||||
Call::Type type,
|
||||
bool isVideo) {
|
||||
struct Performer final {
|
||||
explicit Performer(Fn<void(bool, bool, const Performer &)> callback)
|
||||
: callback(std::move(callback)) {
|
||||
}
|
||||
Fn<void(bool, bool, const Performer &)> callback;
|
||||
};
|
||||
const auto performer = Performer([=](
|
||||
bool video,
|
||||
bool isConfirmed,
|
||||
const Performer &repeater) {
|
||||
const auto delegate = _delegate.get();
|
||||
auto call = std::make_unique<Call>(delegate, user, type, video);
|
||||
if (isConfirmed) {
|
||||
call->applyUserConfirmation();
|
||||
}
|
||||
const auto raw = call.get();
|
||||
|
||||
user->session().account().sessionChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
destroyCall(raw);
|
||||
}, raw->lifetime());
|
||||
user->session().account().sessionChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
destroyCall(raw);
|
||||
}, raw->lifetime());
|
||||
|
||||
if (_currentCall) {
|
||||
_currentCallPanel->replaceCall(raw);
|
||||
std::swap(_currentCall, call);
|
||||
call->hangup();
|
||||
} else {
|
||||
_currentCallPanel = std::make_unique<Panel>(raw);
|
||||
_currentCall = std::move(call);
|
||||
}
|
||||
_currentCallPanel->startOutgoingRequests(
|
||||
) | rpl::start_with_next([=](bool video) {
|
||||
raw->applyUserConfirmation();
|
||||
raw->toggleCameraSharing(video);
|
||||
refreshServerConfig(&user->session());
|
||||
refreshDhConfig();
|
||||
}, raw->lifetime());
|
||||
_currentCallChanges.fire_copy(raw);
|
||||
if (_currentCall) {
|
||||
_currentCallPanel->replaceCall(raw);
|
||||
std::swap(_currentCall, call);
|
||||
call->hangup();
|
||||
} else {
|
||||
_currentCallPanel = std::make_unique<Panel>(raw);
|
||||
_currentCall = std::move(call);
|
||||
}
|
||||
if (raw->state() == Call::State::WaitingUserConfirmation) {
|
||||
_currentCallPanel->startOutgoingRequests(
|
||||
) | rpl::start_with_next([=](bool video) {
|
||||
repeater.callback(video, true, repeater);
|
||||
}, raw->lifetime());
|
||||
} else {
|
||||
refreshServerConfig(&user->session());
|
||||
refreshDhConfig();
|
||||
}
|
||||
_currentCallChanges.fire_copy(raw);
|
||||
});
|
||||
performer.callback(isVideo, false, performer);
|
||||
}
|
||||
|
||||
void Instance::destroyGroupCall(not_null<GroupCall*> call) {
|
||||
|
@ -113,7 +113,7 @@ private:
|
||||
not_null<Media::Audio::Track*> ensureSoundLoaded(const QString &key);
|
||||
void playSoundOnce(const QString &key);
|
||||
|
||||
void createCall(not_null<UserData*> user, CallType type, bool video);
|
||||
void createCall(not_null<UserData*> user, CallType type, bool isVideo);
|
||||
void destroyCall(not_null<Call*> call);
|
||||
|
||||
void createGroupCall(
|
||||
|
@ -80,9 +80,6 @@ Panel::Panel(not_null<Call*> call)
|
||||
st::callScreencastOn,
|
||||
&st::callScreencastOff))
|
||||
, _camera(widget(), st::callCameraMute, &st::callCameraUnmute)
|
||||
, _startVideo(
|
||||
widget(),
|
||||
object_ptr<Ui::CallButton>(widget(), st::callStartVideo))
|
||||
, _mute(
|
||||
widget(),
|
||||
object_ptr<Ui::CallButton>(
|
||||
@ -281,6 +278,7 @@ void Panel::initControls() {
|
||||
} else if (_call->isIncomingWaiting()) {
|
||||
_call->answer();
|
||||
} else if (state == State::WaitingUserConfirmation) {
|
||||
_startOutgoingRequests.fire(false);
|
||||
} else {
|
||||
_call->hangup();
|
||||
}
|
||||
@ -292,7 +290,6 @@ void Panel::initControls() {
|
||||
};
|
||||
_decline->entity()->setClickedCallback(hangupCallback);
|
||||
_cancel->entity()->setClickedCallback(hangupCallback);
|
||||
_startVideo->entity()->setText(tr::lng_call_start_video());
|
||||
|
||||
reinitWithCall(_call);
|
||||
|
||||
@ -334,14 +331,10 @@ rpl::lifetime &Panel::chooseSourceInstanceLifetime() {
|
||||
}
|
||||
|
||||
rpl::producer<bool> Panel::startOutgoingRequests() const {
|
||||
const auto filter = [=] {
|
||||
return _startOutgoingRequests.events(
|
||||
) | rpl::filter([=] {
|
||||
return _call && (_call->state() == State::WaitingUserConfirmation);
|
||||
};
|
||||
return rpl::merge(
|
||||
_startVideo->entity()->clicks(
|
||||
) | rpl::filter(filter) | rpl::map_to(true),
|
||||
_answerHangupRedial->clicks(
|
||||
) | rpl::filter(filter) | rpl::map_to(false));
|
||||
});
|
||||
}
|
||||
|
||||
void Panel::chooseSourceAccepted(
|
||||
@ -478,7 +471,9 @@ void Panel::reinitWithCall(Call *call) {
|
||||
|
||||
rpl::combine(
|
||||
_call->stateValue(),
|
||||
_call->videoOutgoing()->renderNextFrame()
|
||||
rpl::single(
|
||||
rpl::empty_value()
|
||||
) | rpl::then(_call->videoOutgoing()->renderNextFrame())
|
||||
) | rpl::start_with_next([=](State state, auto) {
|
||||
if (state != State::Ended
|
||||
&& state != State::EndedByOtherDevice
|
||||
@ -523,7 +518,9 @@ void Panel::reinitWithCall(Call *call) {
|
||||
_decline->raise();
|
||||
_cancel->raise();
|
||||
_camera->raise();
|
||||
_startVideo->raise();
|
||||
if (_startVideo) {
|
||||
_startVideo->raise();
|
||||
}
|
||||
_mute->raise();
|
||||
|
||||
_powerSaveBlocker = std::make_unique<base::PowerSaveBlocker>(
|
||||
@ -794,7 +791,7 @@ void Panel::updateHangupGeometry() {
|
||||
_camera->moveToLeft(
|
||||
hangupRight - _mute->width() + _screencast->width(),
|
||||
_buttonsTop);
|
||||
if (_startVideo->toggled()) {
|
||||
if (_startVideo) {
|
||||
_startVideo->moveToLeft(_camera->x(), _camera->y());
|
||||
}
|
||||
}
|
||||
@ -849,12 +846,18 @@ void Panel::stateChanged(State state) {
|
||||
if (isBusy) {
|
||||
_powerSaveBlocker = nullptr;
|
||||
}
|
||||
if (_startVideo->toggled() && !isWaitingUser) {
|
||||
_startVideo->toggle(false, anim::type::instant);
|
||||
} else if (!_startVideo->toggled() && isWaitingUser) {
|
||||
_startVideo->toggle(true, anim::type::instant);
|
||||
if (_startVideo && !isWaitingUser) {
|
||||
_startVideo = nullptr;
|
||||
} else if (!_startVideo && isWaitingUser) {
|
||||
_startVideo = base::make_unique_q<Ui::CallButton>(
|
||||
widget(),
|
||||
st::callStartVideo);
|
||||
_startVideo->setText(tr::lng_call_start_video());
|
||||
_startVideo->clicks() | rpl::map_to(true) | rpl::start_to_stream(
|
||||
_startOutgoingRequests,
|
||||
_startVideo->lifetime());
|
||||
}
|
||||
_camera->setVisible(!_startVideo->toggled());
|
||||
_camera->setVisible(!_startVideo);
|
||||
|
||||
const auto toggleButton = [&](auto &&button, bool visible) {
|
||||
button->toggle(
|
||||
|
@ -152,7 +152,7 @@ private:
|
||||
Ui::Animations::Simple _hangupShownProgress;
|
||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _screencast;
|
||||
object_ptr<Ui::CallButton> _camera;
|
||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _startVideo;
|
||||
base::unique_qptr<Ui::CallButton> _startVideo;
|
||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _mute;
|
||||
object_ptr<Ui::FlatLabel> _name;
|
||||
object_ptr<Ui::FlatLabel> _status;
|
||||
@ -167,6 +167,8 @@ private:
|
||||
base::Timer _updateDurationTimer;
|
||||
base::Timer _updateOuterRippleTimer;
|
||||
|
||||
rpl::event_stream<bool> _startOutgoingRequests;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Calls
|
||||
|
Loading…
Reference in New Issue
Block a user