Optimize out most of LastUserInputTime() calls.

Fixes #16118.
This commit is contained in:
John Preston 2021-06-18 19:22:36 +04:00
parent 8897f9e46a
commit e1120d1cb5
12 changed files with 53 additions and 32 deletions

View file

@ -862,8 +862,8 @@ int32 Updates::pts() const {
return _ptsWaiter.current(); return _ptsWaiter.current();
} }
void Updates::updateOnline() { void Updates::updateOnline(crl::time lastNonIdleTime) {
updateOnline(false); updateOnline(lastNonIdleTime, false);
} }
bool Updates::isIdle() const { bool Updates::isIdle() const {
@ -874,15 +874,20 @@ rpl::producer<bool> Updates::isIdleValue() const {
return _isIdle.value(); return _isIdle.value();
} }
void Updates::updateOnline(bool gotOtherOffline) { void Updates::updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline) {
crl::on_main(&session(), [] { Core::App().checkAutoLock(); }); if (!lastNonIdleTime) {
lastNonIdleTime = Core::App().lastNonIdleTime();
}
crl::on_main(&session(), [=] {
Core::App().checkAutoLock(lastNonIdleTime);
});
const auto &config = _session->serverConfig(); const auto &config = _session->serverConfig();
bool isOnline = Core::App().hasActiveWindow(&session()); bool isOnline = Core::App().hasActiveWindow(&session());
int updateIn = config.onlineUpdatePeriod; int updateIn = config.onlineUpdatePeriod;
Assert(updateIn >= 0); Assert(updateIn >= 0);
if (isOnline) { if (isOnline) {
const auto idle = crl::now() - Core::App().lastNonIdleTime(); const auto idle = crl::now() - lastNonIdleTime;
if (idle >= config.offlineIdleTimeout) { if (idle >= config.offlineIdleTimeout) {
isOnline = false; isOnline = false;
if (!isIdle()) { if (!isIdle()) {
@ -933,10 +938,13 @@ void Updates::updateOnline(bool gotOtherOffline) {
_onlineTimer.callOnce(updateIn); _onlineTimer.callOnce(updateIn);
} }
void Updates::checkIdleFinish() { void Updates::checkIdleFinish(crl::time lastNonIdleTime) {
if (crl::now() - Core::App().lastNonIdleTime() if (!lastNonIdleTime) {
lastNonIdleTime = Core::App().lastNonIdleTime();
}
if (crl::now() - lastNonIdleTime
< _session->serverConfig().offlineIdleTimeout) { < _session->serverConfig().offlineIdleTimeout) {
updateOnline(); updateOnline(lastNonIdleTime);
_idleFinishTimer.cancel(); _idleFinishTimer.cancel();
_isIdle = false; _isIdle = false;
} else { } else {
@ -957,9 +965,10 @@ bool Updates::isQuitPrevent() {
return false; return false;
} }
LOG(("Api::Updates prevents quit, sending offline status...")); LOG(("Api::Updates prevents quit, sending offline status..."));
updateOnline(); updateOnline(crl::now());
return true; return true;
} }
void Updates::handleSendActionUpdate( void Updates::handleSendActionUpdate(
PeerId peerId, PeerId peerId,
MsgId rootId, MsgId rootId,
@ -1750,7 +1759,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
if (UserId(d.vuser_id()) == session().userId()) { if (UserId(d.vuser_id()) == session().userId()) {
if (d.vstatus().type() == mtpc_userStatusOffline if (d.vstatus().type() == mtpc_userStatusOffline
|| d.vstatus().type() == mtpc_userStatusEmpty) { || d.vstatus().type() == mtpc_userStatusEmpty) {
updateOnline(true); updateOnline(Core::App().lastNonIdleTime(), true);
if (d.vstatus().type() == mtpc_userStatusOffline) { if (d.vstatus().type() == mtpc_userStatusOffline) {
cSetOtherOnline( cSetOtherOnline(
d.vstatus().c_userStatusOffline().vwas_online().v); d.vstatus().c_userStatusOffline().vwas_online().v);

View file

@ -38,10 +38,10 @@ public:
[[nodiscard]] int32 pts() const; [[nodiscard]] int32 pts() const;
void updateOnline(); void updateOnline(crl::time lastNonIdleTime = 0);
[[nodiscard]] bool isIdle() const; [[nodiscard]] bool isIdle() const;
[[nodiscard]] rpl::producer<bool> isIdleValue() const; [[nodiscard]] rpl::producer<bool> isIdleValue() const;
void checkIdleFinish(); void checkIdleFinish(crl::time lastNonIdleTime = 0);
bool lastWasOnline() const; bool lastWasOnline() const;
crl::time lastSetOnline() const; crl::time lastSetOnline() const;
bool isQuitPrevent(); bool isQuitPrevent();
@ -87,7 +87,7 @@ private:
MsgRange range, MsgRange range,
const MTPupdates_ChannelDifference &result); const MTPupdates_ChannelDifference &result);
void updateOnline(bool gotOtherOffline); void updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline);
void sendPing(); void sendPing();
void getDifferenceByPts(); void getDifferenceByPts();
void getDifferenceAfterFail(); void getDifferenceAfterFail();

View file

@ -45,6 +45,6 @@ void AutoLockBox::durationChanged(int seconds) {
Core::App().settings().setAutoLock(seconds); Core::App().settings().setAutoLock(seconds);
Core::App().saveSettingsDelayed(); Core::App().saveSettingsDelayed();
Core::App().checkAutoLock(); Core::App().checkAutoLock(crl::now());
closeBox(); closeBox();
} }

View file

@ -849,7 +849,7 @@ bool Application::passcodeLocked() const {
void Application::updateNonIdle() { void Application::updateNonIdle() {
_lastNonIdleTime = crl::now(); _lastNonIdleTime = crl::now();
if (const auto session = maybeActiveSession()) { if (const auto session = maybeActiveSession()) {
session->updates().checkIdleFinish(); session->updates().checkIdleFinish(_lastNonIdleTime);
} }
} }
@ -876,19 +876,21 @@ bool Application::someSessionExists() const {
return false; return false;
} }
void Application::checkAutoLock() { void Application::checkAutoLock(crl::time lastNonIdleTime) {
if (!_domain->local().hasLocalPasscode() if (!_domain->local().hasLocalPasscode()
|| passcodeLocked() || passcodeLocked()
|| !someSessionExists()) { || !someSessionExists()) {
_shouldLockAt = 0; _shouldLockAt = 0;
_autoLockTimer.cancel(); _autoLockTimer.cancel();
return; return;
} else if (!lastNonIdleTime) {
lastNonIdleTime = this->lastNonIdleTime();
} }
checkLocalTime(); checkLocalTime();
const auto now = crl::now(); const auto now = crl::now();
const auto shouldLockInMs = _settings.autoLock() * 1000LL; const auto shouldLockInMs = _settings.autoLock() * 1000LL;
const auto checkTimeMs = now - lastNonIdleTime(); const auto checkTimeMs = now - lastNonIdleTime;
if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) { if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) {
_shouldLockAt = 0; _shouldLockAt = 0;
_autoLockTimer.cancel(); _autoLockTimer.cancel();
@ -910,7 +912,7 @@ void Application::checkAutoLockIn(crl::time time) {
void Application::localPasscodeChanged() { void Application::localPasscodeChanged() {
_shouldLockAt = 0; _shouldLockAt = 0;
_autoLockTimer.cancel(); _autoLockTimer.cancel();
checkAutoLock(); checkAutoLock(crl::now());
} }
bool Application::hasActiveWindow(not_null<Main::Session*> session) const { bool Application::hasActiveWindow(not_null<Main::Session*> session) const {

View file

@ -245,7 +245,7 @@ public:
rpl::producer<bool> passcodeLockChanges() const; rpl::producer<bool> passcodeLockChanges() const;
rpl::producer<bool> passcodeLockValue() const; rpl::producer<bool> passcodeLockValue() const;
void checkAutoLock(); void checkAutoLock(crl::time lastNonIdleTime = 0);
void checkAutoLockIn(crl::time time); void checkAutoLockIn(crl::time time);
void localPasscodeChanged(); void localPasscodeChanged();

View file

@ -945,7 +945,7 @@ void MainWindow::sendPaths() {
} }
} }
void MainWindow::updateIsActiveHook() { void MainWindow::activeChangedHook() {
if (const auto controller = sessionController()) { if (const auto controller = sessionController()) {
controller->session().updates().updateOnline(); controller->session().updates().updateOnline();
} }

View file

@ -114,7 +114,7 @@ protected:
void closeEvent(QCloseEvent *e) override; void closeEvent(QCloseEvent *e) override;
void initHook() override; void initHook() override;
void updateIsActiveHook() override; void activeChangedHook() override;
void clearWidgetsHook() override; void clearWidgetsHook() override;
private: private:

View file

@ -237,8 +237,11 @@ void MainWindow::clearWidgets() {
} }
void MainWindow::updateIsActive() { void MainWindow::updateIsActive() {
_isActive = computeIsActive(); const auto isActive = computeIsActive();
updateIsActiveHook(); if (_isActive != isActive) {
_isActive = isActive;
activeChangedHook();
}
} }
bool MainWindow::computeIsActive() const { bool MainWindow::computeIsActive() const {

View file

@ -139,7 +139,7 @@ protected:
virtual void initHook() { virtual void initHook() {
} }
virtual void updateIsActiveHook() { virtual void activeChangedHook() {
} }
virtual void handleActiveChangedHook() { virtual void handleActiveChangedHook() {

View file

@ -158,8 +158,11 @@ float64 Manager::demoMasterOpacity() const {
void Manager::checkLastInput() { void Manager::checkLastInput() {
auto replying = hasReplyingNotification(); auto replying = hasReplyingNotification();
auto waiting = false; auto waiting = false;
for_const (auto &notification, _notifications) { const auto lastInputTime = base::Platform::LastUserInputTimeSupported()
if (!notification->checkLastInput(replying)) { ? std::make_optional(Core::App().lastNonIdleTime())
: std::nullopt;
for (const auto &notification : _notifications) {
if (!notification->checkLastInput(replying, lastInputTime)) {
waiting = true; waiting = true;
} }
} }
@ -682,12 +685,14 @@ void Notification::prepareActionsCache() {
_buttonsCache = App::pixmapFromImageInPlace(std::move(actionsCacheImg)); _buttonsCache = App::pixmapFromImageInPlace(std::move(actionsCacheImg));
} }
bool Notification::checkLastInput(bool hasReplyingNotifications) { bool Notification::checkLastInput(
bool hasReplyingNotifications,
std::optional<crl::time> lastInputTime) {
if (!_waitingForInput) return true; if (!_waitingForInput) return true;
const auto waitForUserInput = base::Platform::LastUserInputTimeSupported() const auto waitForUserInput = lastInputTime.has_value()
? (Core::App().lastNonIdleTime() <= _started) && (*lastInputTime <= _started);
: false;
if (!waitForUserInput) { if (!waitForUserInput) {
_waitingForInput = false; _waitingForInput = false;
if (!hasReplyingNotifications) { if (!hasReplyingNotifications) {

View file

@ -232,7 +232,9 @@ public:
bool unlinkItem(HistoryItem *del); bool unlinkItem(HistoryItem *del);
bool unlinkHistory(History *history = nullptr); bool unlinkHistory(History *history = nullptr);
bool unlinkSession(not_null<Main::Session*> session); bool unlinkSession(not_null<Main::Session*> session);
bool checkLastInput(bool hasReplyingNotifications); bool checkLastInput(
bool hasReplyingNotifications,
std::optional<crl::time> lastInputTime);
protected: protected:
void enterEventHook(QEvent *e) override; void enterEventHook(QEvent *e) override;

View file

@ -67,7 +67,7 @@ void Controller::showAccount(not_null<Main::Account*> account) {
for (auto &[index, account] : _account->domain().accounts()) { for (auto &[index, account] : _account->domain().accounts()) {
if (const auto anotherSession = account->maybeSession()) { if (const auto anotherSession = account->maybeSession()) {
if (anotherSession->uniqueId() == prevSessionUniqueId) { if (anotherSession->uniqueId() == prevSessionUniqueId) {
anotherSession->updates().updateOnline(); anotherSession->updates().updateOnline(crl::now());
return; return;
} }
} }