From e1120d1cb5bc66e962631da5b251056cd3490e05 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 18 Jun 2021 19:22:36 +0400 Subject: [PATCH] Optimize out most of LastUserInputTime() calls. Fixes #16118. --- Telegram/SourceFiles/api/api_updates.cpp | 29 ++++++++++++------- Telegram/SourceFiles/api/api_updates.h | 6 ++-- Telegram/SourceFiles/boxes/auto_lock_box.cpp | 2 +- Telegram/SourceFiles/core/application.cpp | 10 ++++--- Telegram/SourceFiles/core/application.h | 2 +- Telegram/SourceFiles/mainwindow.cpp | 2 +- Telegram/SourceFiles/mainwindow.h | 2 +- Telegram/SourceFiles/window/main_window.cpp | 7 +++-- Telegram/SourceFiles/window/main_window.h | 2 +- .../window/notifications_manager_default.cpp | 17 +++++++---- .../window/notifications_manager_default.h | 4 ++- .../SourceFiles/window/window_controller.cpp | 2 +- 12 files changed, 53 insertions(+), 32 deletions(-) diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index c70b339d3..02ff76013 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -862,8 +862,8 @@ int32 Updates::pts() const { return _ptsWaiter.current(); } -void Updates::updateOnline() { - updateOnline(false); +void Updates::updateOnline(crl::time lastNonIdleTime) { + updateOnline(lastNonIdleTime, false); } bool Updates::isIdle() const { @@ -874,15 +874,20 @@ rpl::producer Updates::isIdleValue() const { return _isIdle.value(); } -void Updates::updateOnline(bool gotOtherOffline) { - crl::on_main(&session(), [] { Core::App().checkAutoLock(); }); +void Updates::updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline) { + if (!lastNonIdleTime) { + lastNonIdleTime = Core::App().lastNonIdleTime(); + } + crl::on_main(&session(), [=] { + Core::App().checkAutoLock(lastNonIdleTime); + }); const auto &config = _session->serverConfig(); bool isOnline = Core::App().hasActiveWindow(&session()); int updateIn = config.onlineUpdatePeriod; Assert(updateIn >= 0); if (isOnline) { - const auto idle = crl::now() - Core::App().lastNonIdleTime(); + const auto idle = crl::now() - lastNonIdleTime; if (idle >= config.offlineIdleTimeout) { isOnline = false; if (!isIdle()) { @@ -933,10 +938,13 @@ void Updates::updateOnline(bool gotOtherOffline) { _onlineTimer.callOnce(updateIn); } -void Updates::checkIdleFinish() { - if (crl::now() - Core::App().lastNonIdleTime() +void Updates::checkIdleFinish(crl::time lastNonIdleTime) { + if (!lastNonIdleTime) { + lastNonIdleTime = Core::App().lastNonIdleTime(); + } + if (crl::now() - lastNonIdleTime < _session->serverConfig().offlineIdleTimeout) { - updateOnline(); + updateOnline(lastNonIdleTime); _idleFinishTimer.cancel(); _isIdle = false; } else { @@ -957,9 +965,10 @@ bool Updates::isQuitPrevent() { return false; } LOG(("Api::Updates prevents quit, sending offline status...")); - updateOnline(); + updateOnline(crl::now()); return true; } + void Updates::handleSendActionUpdate( PeerId peerId, MsgId rootId, @@ -1750,7 +1759,7 @@ void Updates::feedUpdate(const MTPUpdate &update) { if (UserId(d.vuser_id()) == session().userId()) { if (d.vstatus().type() == mtpc_userStatusOffline || d.vstatus().type() == mtpc_userStatusEmpty) { - updateOnline(true); + updateOnline(Core::App().lastNonIdleTime(), true); if (d.vstatus().type() == mtpc_userStatusOffline) { cSetOtherOnline( d.vstatus().c_userStatusOffline().vwas_online().v); diff --git a/Telegram/SourceFiles/api/api_updates.h b/Telegram/SourceFiles/api/api_updates.h index 4981b5b8d..91635592e 100644 --- a/Telegram/SourceFiles/api/api_updates.h +++ b/Telegram/SourceFiles/api/api_updates.h @@ -38,10 +38,10 @@ public: [[nodiscard]] int32 pts() const; - void updateOnline(); + void updateOnline(crl::time lastNonIdleTime = 0); [[nodiscard]] bool isIdle() const; [[nodiscard]] rpl::producer isIdleValue() const; - void checkIdleFinish(); + void checkIdleFinish(crl::time lastNonIdleTime = 0); bool lastWasOnline() const; crl::time lastSetOnline() const; bool isQuitPrevent(); @@ -87,7 +87,7 @@ private: MsgRange range, const MTPupdates_ChannelDifference &result); - void updateOnline(bool gotOtherOffline); + void updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline); void sendPing(); void getDifferenceByPts(); void getDifferenceAfterFail(); diff --git a/Telegram/SourceFiles/boxes/auto_lock_box.cpp b/Telegram/SourceFiles/boxes/auto_lock_box.cpp index a12d4173b..77ef64b2f 100644 --- a/Telegram/SourceFiles/boxes/auto_lock_box.cpp +++ b/Telegram/SourceFiles/boxes/auto_lock_box.cpp @@ -45,6 +45,6 @@ void AutoLockBox::durationChanged(int seconds) { Core::App().settings().setAutoLock(seconds); Core::App().saveSettingsDelayed(); - Core::App().checkAutoLock(); + Core::App().checkAutoLock(crl::now()); closeBox(); } diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 9f4eb4ad6..4214cd2c3 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -849,7 +849,7 @@ bool Application::passcodeLocked() const { void Application::updateNonIdle() { _lastNonIdleTime = crl::now(); if (const auto session = maybeActiveSession()) { - session->updates().checkIdleFinish(); + session->updates().checkIdleFinish(_lastNonIdleTime); } } @@ -876,19 +876,21 @@ bool Application::someSessionExists() const { return false; } -void Application::checkAutoLock() { +void Application::checkAutoLock(crl::time lastNonIdleTime) { if (!_domain->local().hasLocalPasscode() || passcodeLocked() || !someSessionExists()) { _shouldLockAt = 0; _autoLockTimer.cancel(); return; + } else if (!lastNonIdleTime) { + lastNonIdleTime = this->lastNonIdleTime(); } checkLocalTime(); const auto now = crl::now(); const auto shouldLockInMs = _settings.autoLock() * 1000LL; - const auto checkTimeMs = now - lastNonIdleTime(); + const auto checkTimeMs = now - lastNonIdleTime; if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) { _shouldLockAt = 0; _autoLockTimer.cancel(); @@ -910,7 +912,7 @@ void Application::checkAutoLockIn(crl::time time) { void Application::localPasscodeChanged() { _shouldLockAt = 0; _autoLockTimer.cancel(); - checkAutoLock(); + checkAutoLock(crl::now()); } bool Application::hasActiveWindow(not_null session) const { diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index c40a20dce..e14b9b42a 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -245,7 +245,7 @@ public: rpl::producer passcodeLockChanges() const; rpl::producer passcodeLockValue() const; - void checkAutoLock(); + void checkAutoLock(crl::time lastNonIdleTime = 0); void checkAutoLockIn(crl::time time); void localPasscodeChanged(); diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 8e1f62315..8105039c9 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -945,7 +945,7 @@ void MainWindow::sendPaths() { } } -void MainWindow::updateIsActiveHook() { +void MainWindow::activeChangedHook() { if (const auto controller = sessionController()) { controller->session().updates().updateOnline(); } diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index 39cdb2f83..d5f90b578 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -114,7 +114,7 @@ protected: void closeEvent(QCloseEvent *e) override; void initHook() override; - void updateIsActiveHook() override; + void activeChangedHook() override; void clearWidgetsHook() override; private: diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index f7dac8bd4..62b2e5806 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -237,8 +237,11 @@ void MainWindow::clearWidgets() { } void MainWindow::updateIsActive() { - _isActive = computeIsActive(); - updateIsActiveHook(); + const auto isActive = computeIsActive(); + if (_isActive != isActive) { + _isActive = isActive; + activeChangedHook(); + } } bool MainWindow::computeIsActive() const { diff --git a/Telegram/SourceFiles/window/main_window.h b/Telegram/SourceFiles/window/main_window.h index 1bd9595ba..cf545158b 100644 --- a/Telegram/SourceFiles/window/main_window.h +++ b/Telegram/SourceFiles/window/main_window.h @@ -139,7 +139,7 @@ protected: virtual void initHook() { } - virtual void updateIsActiveHook() { + virtual void activeChangedHook() { } virtual void handleActiveChangedHook() { diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 47432713a..93a9efee4 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -158,8 +158,11 @@ float64 Manager::demoMasterOpacity() const { void Manager::checkLastInput() { auto replying = hasReplyingNotification(); auto waiting = false; - for_const (auto ¬ification, _notifications) { - if (!notification->checkLastInput(replying)) { + const auto lastInputTime = base::Platform::LastUserInputTimeSupported() + ? std::make_optional(Core::App().lastNonIdleTime()) + : std::nullopt; + for (const auto ¬ification : _notifications) { + if (!notification->checkLastInput(replying, lastInputTime)) { waiting = true; } } @@ -682,12 +685,14 @@ void Notification::prepareActionsCache() { _buttonsCache = App::pixmapFromImageInPlace(std::move(actionsCacheImg)); } -bool Notification::checkLastInput(bool hasReplyingNotifications) { +bool Notification::checkLastInput( + bool hasReplyingNotifications, + std::optional lastInputTime) { if (!_waitingForInput) return true; - const auto waitForUserInput = base::Platform::LastUserInputTimeSupported() - ? (Core::App().lastNonIdleTime() <= _started) - : false; + const auto waitForUserInput = lastInputTime.has_value() + && (*lastInputTime <= _started); + if (!waitForUserInput) { _waitingForInput = false; if (!hasReplyingNotifications) { diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index 9dcd11ff2..8a3fa7e54 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -232,7 +232,9 @@ public: bool unlinkItem(HistoryItem *del); bool unlinkHistory(History *history = nullptr); bool unlinkSession(not_null session); - bool checkLastInput(bool hasReplyingNotifications); + bool checkLastInput( + bool hasReplyingNotifications, + std::optional lastInputTime); protected: void enterEventHook(QEvent *e) override; diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index dd09b1c4e..bd23b329a 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -67,7 +67,7 @@ void Controller::showAccount(not_null account) { for (auto &[index, account] : _account->domain().accounts()) { if (const auto anotherSession = account->maybeSession()) { if (anotherSession->uniqueId() == prevSessionUniqueId) { - anotherSession->updates().updateOnline(); + anotherSession->updates().updateOnline(crl::now()); return; } }