Move ApiWrap to AuthSession.

Also send all ApiWrap requests as an MTP::Sender.
Also create AuthSession only after starting MTProto.
This commit is contained in:
John Preston 2017-04-06 22:02:40 +03:00
parent 835b1801bc
commit 0d0307e175
16 changed files with 553 additions and 610 deletions

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#pragma once
#include "core/single_timer.h"
#include "mtproto/sender.h"
namespace Api {
@ -34,10 +35,9 @@ inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Cha
} // namespace Api
class ApiWrap : public QObject, public RPCSender {
class ApiWrap : public QObject, private MTP::Sender {
public:
ApiWrap(QObject *parent);
void init();
ApiWrap();
using RequestMessageDataCallback = base::lambda<void(ChannelData*, MsgId)>;
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback);
@ -45,12 +45,12 @@ public:
void requestFullPeer(PeerData *peer);
void requestPeer(PeerData *peer);
void requestPeers(const QList<PeerData*> &peers);
void requestLastParticipants(ChannelData *peer, bool fromStart = true);
void requestBots(ChannelData *peer);
void requestLastParticipants(ChannelData *channel, bool fromStart = true);
void requestBots(ChannelData *channel);
void requestParticipantsCountDelayed(ChannelData *channel);
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
void processFullPeer(PeerData *peer, const MTPUserFull &result);
void processFullPeer(UserData *user, const MTPUserFull &result);
void requestSelfParticipant(ChannelData *channel);
void kickParticipant(PeerData *peer, UserData *user);
@ -87,105 +87,72 @@ public:
~ApiWrap();
private:
struct MessageDataRequest {
using Callbacks = QList<RequestMessageDataCallback>;
mtpRequestId requestId = 0;
Callbacks callbacks;
};
using MessageDataRequests = QMap<MsgId, MessageDataRequest>;
void updatesReceived(const MTPUpdates &updates);
void resolveMessageDatas();
void gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
struct MessageDataRequest {
using Callbacks = QList<RequestMessageDataCallback>;
mtpRequestId req = 0;
Callbacks callbacks;
};
typedef QMap<MsgId, MessageDataRequest> MessageDataRequests;
MessageDataRequests _messageDataRequests;
typedef QMap<ChannelData*, MessageDataRequests> ChannelMessageDataRequests;
ChannelMessageDataRequests _channelMessageDataRequests;
SingleQueuedInvokation _messageDataResolveDelayed;
typedef QVector<MTPint> MessageIds;
MessageIds collectMessageIds(const MessageDataRequests &requests);
void gotMessageDatas(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId requestId);
QVector<MTPint> collectMessageIds(const MessageDataRequests &requests);
MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false);
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
void gotUserFull(PeerData *peer, const MTPUserFull &result, mtpRequestId req);
bool gotPeerFullFailed(PeerData *peer, const RPCError &err);
typedef QMap<PeerData*, mtpRequestId> PeerRequests;
PeerRequests _fullPeerRequests;
void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req);
void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req);
void resolveWebPages();
void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
void gotChat(PeerData *peer, const MTPmessages_Chats &result);
void gotUser(PeerData *peer, const MTPVector<MTPUser> &result);
void gotChats(const MTPmessages_Chats &result);
void gotUsers(const MTPVector<MTPUser> &result);
bool gotPeerFailed(PeerData *peer, const RPCError &err);
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
void stickerSetDisenabled(mtpRequestId requestId);
void stickersSaveOrder();
MessageDataRequests _messageDataRequests;
QMap<ChannelData*, MessageDataRequests> _channelMessageDataRequests;
SingleQueuedInvokation _messageDataResolveDelayed;
using PeerRequests = QMap<PeerData*, mtpRequestId>;
PeerRequests _fullPeerRequests;
PeerRequests _peerRequests;
void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req);
bool lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req);
PeerRequests _participantsRequests, _botsRequests;
PeerRequests _participantsRequests;
PeerRequests _botsRequests;
typedef QPair<PeerData*, UserData*> KickRequest;
typedef QMap<KickRequest, mtpRequestId> KickRequests;
void kickParticipantDone(KickRequest kick, const MTPUpdates &updates, mtpRequestId req);
bool kickParticipantFail(KickRequest kick, const RPCError &error, mtpRequestId req);
KickRequests _kickRequests;
void gotSelfParticipant(ChannelData *channel, const MTPchannels_ChannelParticipant &result);
bool gotSelfParticipantFail(ChannelData *channel, const RPCError &error);
typedef QMap<ChannelData*, mtpRequestId> SelfParticipantRequests;
SelfParticipantRequests _selfParticipantRequests;
QMap<ChannelData*, mtpRequestId> _selfParticipantRequests;
void resolveWebPages();
void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
typedef QMap<WebPageData*, mtpRequestId> WebPagesPending;
WebPagesPending _webPagesPending;
QMap<WebPageData*, mtpRequestId> _webPagesPending;
SingleTimer _webPagesTimer;
QMap<uint64, QPair<uint64, mtpRequestId> > _stickerSetRequests;
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
bool gotStickerSetFail(uint64 setId, const RPCError &error);
QMap<ChannelData*, mtpRequestId> _channelAmInRequests;
void channelAmInUpdated(ChannelData *channel);
void channelAmInDone(ChannelData *channel, const MTPUpdates &updates);
bool channelAmInFail(ChannelData *channel, const RPCError &error);
QMap<UserData*, mtpRequestId> _blockRequests;
void blockDone(UserData *user, const MTPBool &result);
void unblockDone(UserData *user, const MTPBool &result);
bool blockFail(UserData *user, const RPCError &error);
QMap<PeerData*, mtpRequestId> _exportInviteRequests;
void exportInviteDone(PeerData *peer, const MTPExportedChatInvite &result);
bool exportInviteFail(PeerData *peer, const RPCError &error);
QMap<PeerData*, mtpRequestId> _notifySettingRequests;
void notifySettingDone(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
bool notifySettingFail(PeerData *peer, const RPCError &error);
QMap<History*, mtpRequestId> _draftsSaveRequestIds;
SingleTimer _draftsSaveTimer;
void saveCloudDraftDone(History *history, const MTPBool &result, mtpRequestId requestId);
bool saveCloudDraftFail(History *history, const RPCError &error, mtpRequestId requestId);
OrderedSet<mtpRequestId> _stickerSetDisenableRequests;
void stickerSetDisenableDone(const MTPmessages_StickerSetInstallResult &result, mtpRequestId req);
bool stickerSetDisenableFail(const RPCError &error, mtpRequestId req);
Stickers::Order _stickersOrder;
mtpRequestId _stickersReorderRequestId = 0;
void stickersSaveOrder();
void stickersReorderDone(const MTPBool &result);
bool stickersReorderFail(const RPCError &result);
mtpRequestId _stickersClearRecentRequestId = 0;
void stickersClearRecentDone(const MTPBool &result);
bool stickersClearRecentFail(const RPCError &result);
QMap<mtpTypeId, mtpRequestId> _privacySaveRequests;
void savePrivacyDone(mtpTypeId keyTypeId, const MTPaccount_PrivacyRules &result);
bool savePrivacyFail(mtpTypeId keyTypeId, const RPCError &error);
mtpRequestId _contactsStatusesRequestId = 0;
void contactsStatusesDone(const MTPVector<MTPContactStatus> &result);
bool contactsStatusesFail(const RPCError &error);
base::Observable<PeerData*> _fullPeerUpdated;

View File

@ -191,7 +191,7 @@ namespace App {
}
ApiWrap *api() {
return main() ? main()->api() : 0;
return AuthSession::Exists() ? &AuthSession::Current().api() : nullptr;
}
namespace {

View File

@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "auth_session.h"
#include "apiwrap.h"
#include "messenger.h"
#include "storage/file_download.h"
#include "window/notifications_manager.h"
@ -75,6 +76,7 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
AuthSession::AuthSession(UserId userId)
: _userId(userId)
, _api(std::make_unique<ApiWrap>())
, _downloader(std::make_unique<Storage::Downloader>())
, _notifications(std::make_unique<Window::Notifications::System>(this)) {
Expects(_userId != 0);

View File

@ -30,6 +30,8 @@ class System;
} // namespace Notifications
} // namespace Window
class ApiWrap;
enum class EmojiPanelTab {
Emoji,
Stickers,
@ -121,12 +123,17 @@ public:
return _data;
}
ApiWrap &api() {
return *_api;
}
~AuthSession();
private:
UserId _userId = 0;
const UserId _userId = 0;
AuthSessionData _data;
const std::unique_ptr<ApiWrap> _api;
const std::unique_ptr<Storage::Downloader> _downloader;
const std::unique_ptr<Window::Notifications::System> _notifications;

View File

@ -345,11 +345,6 @@ public:
void searchMessages(const QString &query, PeerData *inPeer = 0);
void onSearchMore();
void rpcClear() override {
_inner->rpcClear();
RPCSender::rpcClear();
}
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
void notify_historyMuteUpdated(History *history);

View File

@ -170,7 +170,7 @@ void CodeWidget::finished() {
Step::finished();
_checkRequest->stop();
_callTimer->stop();
rpcClear();
rpcInvalidate();
cancelled();
_sentCode.clear();

View File

@ -249,7 +249,7 @@ void PhoneWidget::activate() {
void PhoneWidget::finished() {
Step::finished();
_checkRequest->stop();
rpcClear();
rpcInvalidate();
cancelled();
}

View File

@ -82,8 +82,7 @@ MainWidget::MainWidget(QWidget *parent, std::unique_ptr<Window::Controller> cont
, _dialogs(this, _controller.get())
, _history(this, _controller.get())
, _playerPlaylist(this, Media::Player::Panel::Layout::OnlyPlaylist)
, _playerPanel(this, Media::Player::Panel::Layout::Full)
, _api(new ApiWrap(this)) {
, _playerPanel(this, Media::Player::Panel::Layout::Full) {
Messenger::Instance().mtp()->setUpdatesHandler(rpcDone(&MainWidget::updateReceived));
Messenger::Instance().mtp()->setGlobalFailHandler(rpcFail(&MainWidget::updateFail));
@ -110,7 +109,7 @@ MainWidget::MainWidget(QWidget *parent, std::unique_ptr<Window::Controller> cont
handleAudioUpdate(audioId);
}
});
subscribe(_api->fullPeerUpdated(), [this](PeerData *peer) {
subscribe(AuthSession::Current().api().fullPeerUpdated(), [this](PeerData *peer) {
emit peerUpdated(peer);
});
subscribe(Global::RefDialogsListFocused(), [this](bool) {
@ -179,8 +178,6 @@ MainWidget::MainWidget(QWidget *parent, std::unique_ptr<Window::Controller> cont
_sideResizeArea->installEventFilter(this);
_api->init();
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
Sandbox::startUpdateCheck();
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
@ -480,14 +477,6 @@ void MainWidget::onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data)
}
}
void MainWidget::rpcClear() {
_history->rpcClear();
_dialogs->rpcClear();
if (_overview) _overview->rpcClear();
if (_api) _api->rpcClear();
RPCSender::rpcClear();
}
bool MainWidget::isItemVisible(HistoryItem *item) {
if (isHidden() || _a_show.animating()) {
return false;
@ -1863,10 +1852,6 @@ ImagePtr MainWidget::newBackgroundThumb() {
return _background ? _background->thumb : ImagePtr();
}
ApiWrap *MainWidget::api() {
return _api.get();
}
void MainWidget::messageDataReceived(ChannelData *channel, MsgId msgId) {
_history->messageDataReceived(channel, msgId);
}
@ -4549,7 +4534,7 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
if (peerId) {
if (auto item = App::histItemById(peerToChannel(peerId), d.vid.v)) {
if (d.has_entities() && !mentionUsersLoaded(d.ventities)) {
api()->requestMessageData(item->history()->peer->asChannel(), item->id, ApiWrap::RequestMessageDataCallback());
AuthSession::Current().api().requestMessageData(item->history()->peer->asChannel(), item->id, ApiWrap::RequestMessageDataCallback());
}
auto entities = d.has_entities() ? entitiesFromMTP(d.ventities.v) : EntitiesInText();
item->setText({ text, entities });

View File

@ -55,7 +55,6 @@ struct SectionSlideParams;
} // namespace Window
class MainWindow;
class ApiWrap;
class ConfirmBox;
class DialogsWidget;
class HistoryWidget;
@ -334,7 +333,6 @@ public:
void checkChatBackground();
ImagePtr newBackgroundThumb();
ApiWrap *api();
void messageDataReceived(ChannelData *channel, MsgId msgId);
void updateBotKeyboard(History *h);
@ -374,8 +372,6 @@ public:
bool contentOverlapped(const QRect &globalRect);
void rpcClear() override;
bool isItemVisible(HistoryItem *item);
void documentLoadProgress(DocumentData *document);
@ -668,8 +664,6 @@ private:
std::unique_ptr<App::WallPaper> _background;
std::unique_ptr<ApiWrap> _api;
bool _resizingSide = false;
int _resizingSideShift = 0;

View File

@ -50,6 +50,8 @@ Messenger *Messenger::InstancePointer() {
}
struct Messenger::Private {
UserId authSessionUserId = 0;
std::unique_ptr<AuthSessionData> authSessionData;
MTP::Instance::Config mtpConfig;
MTP::AuthKeysList mtpKeysToDestroy;
};
@ -159,12 +161,12 @@ Messenger::Messenger() : QObject()
}
void Messenger::setMtpMainDcId(MTP::DcId mainDcId) {
t_assert(!_mtproto);
Expects(!_mtproto);
_private->mtpConfig.mainDcId = mainDcId;
}
void Messenger::setMtpKey(MTP::DcId dcId, const MTP::AuthKey::Data &keyData) {
t_assert(!_mtproto);
Expects(!_mtproto);
_private->mtpConfig.keys.push_back(std::make_shared<MTP::AuthKey>(MTP::AuthKey::Type::ReadFromFile, dcId, keyData));
}
@ -213,9 +215,27 @@ QByteArray Messenger::serializeMtpAuthorization() const {
return serialize(_private->mtpConfig.mainDcId, keys, keysToDestroy);
}
void Messenger::setAuthSessionUserId(UserId userId) {
Expects(!authSession());
_private->authSessionUserId = userId;
}
void Messenger::setAuthSessionData(std::unique_ptr<AuthSessionData> data) {
Expects(!authSession());
_private->authSessionData = std::move(data);
}
AuthSessionData *Messenger::getAuthSessionData() {
if (_private->authSessionUserId) {
return _private->authSessionData.get();
} else if (AuthSession::Exists()) {
return &AuthSession::Current().data();
}
return nullptr;
}
void Messenger::setMtpAuthorization(const QByteArray &serialized) {
t_assert(!_mtproto);
t_assert(!authSession());
Expects(!_mtproto);
auto readonly = serialized;
QBuffer buffer(&readonly);
@ -233,9 +253,7 @@ void Messenger::setMtpAuthorization(const QByteArray &serialized) {
return;
}
if (userId) {
authSessionCreate(userId);
}
setAuthSessionUserId(userId);
_private->mtpConfig.mainDcId = mainDcId;
auto readKeys = [&stream](auto &keys) {
@ -261,7 +279,7 @@ void Messenger::setMtpAuthorization(const QByteArray &serialized) {
}
void Messenger::startMtp() {
t_assert(!_mtproto);
Expects(!_mtproto);
_mtproto = std::make_unique<MTP::Instance>(_dcOptions.get(), MTP::Instance::Mode::Normal, base::take(_private->mtpConfig));
_private->mtpConfig.mainDcId = _mtproto->mainDcId();
@ -279,6 +297,16 @@ void Messenger::startMtp() {
if (!_private->mtpKeysToDestroy.empty()) {
destroyMtpKeys(base::take(_private->mtpKeysToDestroy));
}
if (_private->authSessionUserId) {
authSessionCreate(base::take(_private->authSessionUserId));
}
if (_private->authSessionData) {
if (_authSession) {
_authSession->data().copyFrom(*_private->authSessionData);
}
_private->authSessionData.reset();
}
}
void Messenger::destroyMtpKeys(MTP::AuthKeysList &&keys) {
@ -583,12 +611,15 @@ void Messenger::onSwitchTestMode() {
}
void Messenger::authSessionCreate(UserId userId) {
Expects(_mtproto != nullptr);
_authSession = std::make_unique<AuthSession>(userId);
authSessionChanged().notify();
}
void Messenger::authSessionDestroy() {
_authSession.reset();
_private->authSessionData.reset();
_private->authSessionUserId = 0;
authSessionChanged().notify();
}

View File

@ -28,6 +28,7 @@ class Instance;
} // namespace MTP
class AuthSession;
class AuthSessionData;
class MainWidget;
class FileUploader;
class Translator;
@ -57,10 +58,17 @@ public:
return _dcOptions.get();
}
// Set from legacy storage.
void setMtpMainDcId(MTP::DcId mainDcId);
void setMtpKey(MTP::DcId dcId, const MTP::AuthKey::Data &keyData);
void setAuthSessionUserId(UserId userId);
void setAuthSessionData(std::unique_ptr<AuthSessionData> data);
AuthSessionData *getAuthSessionData();
// Serialization.
QByteArray serializeMtpAuthorization() const;
void setMtpAuthorization(const QByteArray &serialized);
void startMtp();
MTP::Instance *mtp() {
return _mtproto.get();

View File

@ -837,14 +837,12 @@ public:
protected:
void rpcInvalidate() {
for (DoneHandlers::iterator i = _rpcDoneHandlers.begin(), e = _rpcDoneHandlers.end(); i != e; ++i) {
(*i)->invalidate();
for (auto handler : base::take(_rpcDoneHandlers)) {
handler->invalidate();
}
_rpcDoneHandlers.clear();
for (FailHandlers::iterator i = _rpcFailHandlers.begin(), e = _rpcFailHandlers.end(); i != e; ++i) {
(*i)->invalidate();
for (auto handler : base::take(_rpcFailHandlers)) {
handler->invalidate();
}
_rpcFailHandlers.clear();
}
};

View File

@ -287,6 +287,10 @@ public:
SentRequestWrap request(mtpRequestId requestId) noexcept WARN_UNUSED_RESULT;
void requestSendDelayed() {
MTP::sendAnything();
}
private:
class RequestWrap {
public:

View File

@ -192,7 +192,7 @@ public:
}
void stop() override {
rpcClear();
rpcInvalidate();
}
~mtpFileLoader();

View File

@ -925,9 +925,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
DEBUG_LOG(("MTP Info: user found, dc %1, uid %2").arg(dcId).arg(userId));
Messenger::Instance().setMtpMainDcId(dcId);
if (userId) {
Messenger::Instance().authSessionCreate(UserId(userId));
}
Messenger::Instance().setAuthSessionUserId(userId);
} break;
case dbiKey: {
@ -1709,7 +1707,7 @@ void _writeUserSettings() {
recentEmojiPreloadData.push_back(qMakePair(item.first->id(), item.second));
}
}
auto userDataInstance = AuthSessionDataCache ? AuthSessionDataCache.get() : AuthSession::Exists() ? &AuthSession::Current().data() : nullptr;
auto userDataInstance = AuthSessionDataCache ? AuthSessionDataCache.get() : Messenger::Instance().getAuthSessionData();
auto userData = userDataInstance ? userDataInstance->serialize() : QByteArray();
uint32 size = 21 * (sizeof(quint32) + sizeof(qint32));
@ -2065,12 +2063,7 @@ ReadMapState _readMap(const QByteArray &pass) {
_readUserSettings();
_readMtpData();
if (AuthSessionDataCache) {
if (AuthSession::Exists()) {
AuthSession::Current().data().copyFrom(*AuthSessionDataCache);
}
AuthSessionDataCache.reset();
}
Messenger::Instance().setAuthSessionData(std::move(AuthSessionDataCache));
LOG(("Map read time: %1").arg(getms() - ms));
if (_oldSettingsVersion < AppVersion) {