1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include "core/core_settings.h" 11 #include "mtproto/mtproto_auth_key.h" 12 #include "mtproto/mtproto_proxy_data.h" 13 #include "base/timer.h" 14 15 class MainWindow; 16 class MainWidget; 17 class FileUploader; 18 class Translator; 19 20 namespace Storage { 21 class Databases; 22 } // namespace Storage 23 24 namespace Window { 25 class Controller; 26 } // namespace Window 27 28 namespace Window { 29 namespace Notifications { 30 class System; 31 } // namespace Notifications 32 } // namespace Window 33 34 namespace ChatHelpers { 35 class EmojiKeywords; 36 } // namespace ChatHelpers 37 38 namespace App { 39 void quit(); 40 } // namespace App 41 42 namespace Main { 43 class Domain; 44 class Account; 45 class Session; 46 } // namespace Main 47 48 namespace Ui { 49 namespace Animations { 50 class Manager; 51 } // namespace Animations 52 namespace Emoji { 53 class UniversalImages; 54 } // namespace Emoji 55 class BoxContent; 56 } // namespace Ui 57 58 namespace MTP { 59 class Config; 60 class Instance; 61 class AuthKey; 62 using AuthKeyPtr = std::shared_ptr<AuthKey>; 63 using AuthKeysList = std::vector<AuthKeyPtr>; 64 } // namespace MTP 65 66 namespace Media { 67 namespace Audio { 68 class Instance; 69 } // namespace Audio 70 namespace View { 71 class OverlayWidget; 72 } // namespace View 73 namespace Player { 74 class FloatController; 75 class FloatDelegate; 76 } // namespace Player 77 } // namespace Media 78 79 namespace Lang { 80 class Instance; 81 class Translator; 82 class CloudManager; 83 } // namespace Lang 84 85 namespace Data { 86 struct CloudTheme; 87 } // namespace Data 88 89 namespace Stickers { 90 class EmojiImageLoader; 91 } // namespace Stickers 92 93 namespace Export { 94 class Manager; 95 } // namespace Export 96 97 namespace Calls { 98 class Instance; 99 } // namespace Calls 100 101 namespace Core { 102 103 class Launcher; 104 struct LocalUrlHandler; 105 106 class Application final : public QObject { 107 public: 108 struct ProxyChange { 109 MTP::ProxyData was; 110 MTP::ProxyData now; 111 }; 112 113 Application(not_null<Launcher*> launcher); 114 Application(const Application &other) = delete; 115 Application &operator=(const Application &other) = delete; 116 ~Application(); 117 launcher()118 [[nodiscard]] not_null<Launcher*> launcher() const { 119 return _launcher; 120 } 121 122 void run(); 123 animationManager()124 [[nodiscard]] Ui::Animations::Manager &animationManager() const { 125 return *_animationsManager; 126 } notifications()127 [[nodiscard]] Window::Notifications::System ¬ifications() const { 128 Expects(_notifications != nullptr); 129 130 return *_notifications; 131 } 132 133 // Windows interface. 134 bool hasActiveWindow(not_null<Main::Session*> session) const; 135 void saveCurrentDraftsToHistories(); 136 [[nodiscard]] Window::Controller *activeWindow() const; 137 bool closeActiveWindow(); 138 bool minimizeActiveWindow(); 139 [[nodiscard]] QWidget *getFileDialogParent(); 140 void notifyFileDialogShown(bool shown); 141 void checkSystemDarkMode(); 142 143 // Media view interface. 144 void checkMediaViewActivation(); 145 bool hideMediaView(); 146 147 [[nodiscard]] QPoint getPointForCallPanelCenter() const; 148 149 void startSettingsAndBackground(); settings()150 [[nodiscard]] Settings &settings() { 151 return _settings; 152 } 153 void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay); 154 void saveSettings(); 155 156 // Fallback config and proxy. 157 [[nodiscard]] MTP::Config &fallbackProductionConfig() const; 158 void refreshFallbackProductionConfig(const MTP::Config &config); 159 void constructFallbackProductionConfig(const QByteArray &serialized); 160 void setCurrentProxy( 161 const MTP::ProxyData &proxy, 162 MTP::ProxyData::Settings settings); 163 [[nodiscard]] rpl::producer<ProxyChange> proxyChanges() const; 164 void badMtprotoConfigurationError(); 165 166 // Databases. databases()167 [[nodiscard]] Storage::Databases &databases() { 168 return *_databases; 169 } 170 171 // Domain component. domain()172 [[nodiscard]] Main::Domain &domain() const { 173 return *_domain; 174 } 175 [[nodiscard]] Main::Account &activeAccount() const; 176 [[nodiscard]] bool someSessionExists() const; exportManager()177 [[nodiscard]] Export::Manager &exportManager() const { 178 return *_exportManager; 179 } 180 [[nodiscard]] bool exportPreventsQuit(); 181 182 // Main::Session component. 183 Main::Session *maybeActiveSession() const; 184 [[nodiscard]] int unreadBadge() const; 185 [[nodiscard]] bool unreadBadgeMuted() const; 186 [[nodiscard]] rpl::producer<> unreadBadgeChanges() const; 187 188 // Media component. audio()189 [[nodiscard]] Media::Audio::Instance &audio() { 190 return *_audio; 191 } 192 193 // Langpack and emoji keywords. langpack()194 [[nodiscard]] Lang::Instance &langpack() { 195 return *_langpack; 196 } langCloudManager()197 [[nodiscard]] Lang::CloudManager *langCloudManager() { 198 return _langCloudManager.get(); 199 } 200 [[nodiscard]] bool offerLegacyLangPackSwitch() const; 201 [[nodiscard]] bool canApplyLangPackWithoutRestart() const; emojiKeywords()202 [[nodiscard]] ChatHelpers::EmojiKeywords &emojiKeywords() { 203 return *_emojiKeywords; 204 } 205 [[nodiscard]] auto emojiImageLoader() const 206 -> const crl::object_on_queue<Stickers::EmojiImageLoader> & { 207 return _emojiImageLoader; 208 } 209 210 // Internal links. 211 void checkStartUrl(); 212 bool openLocalUrl(const QString &url, QVariant context); 213 bool openInternalUrl(const QString &url, QVariant context); 214 [[nodiscard]] QString changelogLink() const; 215 216 // Float player. 217 void setDefaultFloatPlayerDelegate( 218 not_null<Media::Player::FloatDelegate*> delegate); 219 void replaceFloatPlayerDelegate( 220 not_null<Media::Player::FloatDelegate*> replacement); 221 void restoreFloatPlayerDelegate( 222 not_null<Media::Player::FloatDelegate*> replacement); 223 [[nodiscard]] rpl::producer<FullMsgId> floatPlayerClosed() const; 224 225 // Calls. calls()226 Calls::Instance &calls() const { 227 return *_calls; 228 } 229 230 void logout(Main::Account *account = nullptr); 231 void forceLogOut( 232 not_null<Main::Account*> account, 233 const TextWithEntities &explanation); 234 void checkLocalTime(); 235 void lockByPasscode(); 236 void unlockPasscode(); 237 [[nodiscard]] bool passcodeLocked() const; 238 rpl::producer<bool> passcodeLockChanges() const; 239 rpl::producer<bool> passcodeLockValue() const; 240 241 void checkAutoLock(crl::time lastNonIdleTime = 0); 242 void checkAutoLockIn(crl::time time); 243 void localPasscodeChanged(); 244 245 [[nodiscard]] crl::time lastNonIdleTime() const; 246 void updateNonIdle(); 247 248 void registerLeaveSubscription(not_null<QWidget*> widget); 249 void unregisterLeaveSubscription(not_null<QWidget*> widget); 250 251 // Sandbox interface. 252 void postponeCall(FnMut<void()> &&callable); 253 void refreshGlobalProxy(); 254 255 void quitPreventFinished(); 256 257 void handleAppActivated(); 258 void handleAppDeactivated(); 259 [[nodiscard]] rpl::producer<bool> appDeactivatedValue() const; 260 261 void switchDebugMode(); 262 void switchFreeType(); 263 void writeInstallBetaVersionsSetting(); 264 265 void preventOrInvoke(Fn<void()> &&callback); 266 267 void call_handleObservables(); 268 269 // Global runtime variables. 270 void setScreenIsLocked(bool locked); 271 bool screenIsLocked() const; 272 273 static void RegisterUrlScheme(); 274 275 protected: 276 bool eventFilter(QObject *object, QEvent *event) override; 277 278 private: 279 static constexpr auto kDefaultSaveDelay = crl::time(1000); 280 281 friend bool IsAppLaunched(); 282 friend Application &App(); 283 284 void clearEmojiSourceImages(); 285 [[nodiscard]] auto prepareEmojiSourceImages() 286 -> std::shared_ptr<Ui::Emoji::UniversalImages>; 287 void startLocalStorage(); 288 void startShortcuts(); 289 void startDomain(); 290 void startEmojiImageLoader(); 291 void startSystemDarkModeViewer(); 292 293 friend void App::quit(); 294 static void QuitAttempt(); 295 void quitDelayed(); 296 [[nodiscard]] bool readyToQuit(); 297 298 void showOpenGLCrashNotification(); 299 void clearPasscodeLock(); 300 301 bool openCustomUrl( 302 const QString &protocol, 303 const std::vector<LocalUrlHandler> &handlers, 304 const QString &url, 305 const QVariant &context); 306 307 static Application *Instance; 308 struct InstanceSetter { InstanceSetterInstanceSetter309 InstanceSetter(not_null<Application*> instance) { 310 Expects(Instance == nullptr); 311 312 Instance = instance; 313 } 314 }; 315 InstanceSetter _setter = { this }; 316 317 not_null<Launcher*> _launcher; 318 rpl::event_stream<ProxyChange> _proxyChanges; 319 320 // Some fields are just moved from the declaration. 321 struct Private; 322 const std::unique_ptr<Private> _private; 323 Settings _settings; 324 325 const std::unique_ptr<Storage::Databases> _databases; 326 const std::unique_ptr<Ui::Animations::Manager> _animationsManager; 327 crl::object_on_queue<Stickers::EmojiImageLoader> _emojiImageLoader; 328 base::Timer _clearEmojiImageLoaderTimer; 329 const std::unique_ptr<Media::Audio::Instance> _audio; 330 mutable std::unique_ptr<MTP::Config> _fallbackProductionConfig; 331 332 // Notifications should be destroyed before _audio, after _domain. 333 // Mutable because is created in run() after OpenSSL is inited. 334 std::unique_ptr<Window::Notifications::System> _notifications; 335 336 const std::unique_ptr<Main::Domain> _domain; 337 const std::unique_ptr<Export::Manager> _exportManager; 338 const std::unique_ptr<Calls::Instance> _calls; 339 std::unique_ptr<Window::Controller> _window; 340 std::unique_ptr<Media::View::OverlayWidget> _mediaView; 341 const std::unique_ptr<Lang::Instance> _langpack; 342 const std::unique_ptr<Lang::CloudManager> _langCloudManager; 343 const std::unique_ptr<ChatHelpers::EmojiKeywords> _emojiKeywords; 344 std::unique_ptr<Lang::Translator> _translator; 345 QPointer<Ui::BoxContent> _badProxyDisableBox; 346 347 std::unique_ptr<Media::Player::FloatController> _floatPlayers; 348 Media::Player::FloatDelegate *_defaultFloatPlayerDelegate = nullptr; 349 Media::Player::FloatDelegate *_replacementFloatPlayerDelegate = nullptr; 350 351 rpl::variable<bool> _passcodeLock; 352 bool _screenIsLocked = false; 353 354 crl::time _shouldLockAt = 0; 355 base::Timer _autoLockTimer; 356 357 std::optional<base::Timer> _saveSettingsTimer; 358 359 struct LeaveFilter { 360 std::vector<QPointer<QWidget>> registered; 361 QPointer<QObject> filter; 362 }; 363 base::flat_map<not_null<QWidget*>, LeaveFilter> _leaveFilters; 364 365 rpl::lifetime _lifetime; 366 367 crl::time _lastNonIdleTime = 0; 368 369 }; 370 371 [[nodiscard]] bool IsAppLaunched(); 372 [[nodiscard]] Application &App(); 373 374 } // namespace Core 375