sandbox.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "mtproto/mtproto_proxy_data.h"
  9. #include <QtWidgets/QApplication>
  10. #include <QtNetwork/QLocalServer>
  11. #include <QtNetwork/QLocalSocket>
  12. #include <QtCore/QAbstractNativeEventFilter>
  13. class QLockFile;
  14. namespace Core {
  15. class UpdateChecker;
  16. class Application;
  17. class Sandbox final
  18. : public QApplication
  19. , private QAbstractNativeEventFilter {
  20. private:
  21. auto createEventNestingLevel() {
  22. incrementEventNestingLevel();
  23. return gsl::finally([=] { decrementEventNestingLevel(); });
  24. }
  25. public:
  26. Sandbox(int &argc, char **argv);
  27. Sandbox(const Sandbox &other) = delete;
  28. Sandbox &operator=(const Sandbox &other) = delete;
  29. int start();
  30. void refreshGlobalProxy();
  31. void postponeCall(FnMut<void()> &&callable);
  32. bool notify(QObject *receiver, QEvent *e) override;
  33. template <typename Callable>
  34. auto customEnterFromEventLoop(Callable &&callable) {
  35. registerEnterFromEventLoop();
  36. const auto wrap = createEventNestingLevel();
  37. return callable();
  38. }
  39. rpl::producer<> widgetUpdateRequests() const;
  40. MTP::ProxyData sandboxProxy() const;
  41. static Sandbox &Instance() {
  42. Expects(QCoreApplication::instance() != nullptr);
  43. return *static_cast<Sandbox*>(QCoreApplication::instance());
  44. }
  45. static void QuitWhenStarted();
  46. ~Sandbox();
  47. protected:
  48. bool event(QEvent *e) override;
  49. private:
  50. typedef QPair<QLocalSocket*, QByteArray> LocalClient;
  51. typedef QList<LocalClient> LocalClients;
  52. struct PostponedCall {
  53. int loopNestingLevel = 0;
  54. FnMut<void()> callable;
  55. };
  56. bool notifyOrInvoke(QObject *receiver, QEvent *e);
  57. void closeApplication(); // will be done in aboutToQuit()
  58. void checkForQuit(); // will be done in exec()
  59. void checkForEmptyLoopNestingLevel();
  60. void registerEnterFromEventLoop();
  61. void incrementEventNestingLevel();
  62. void decrementEventNestingLevel();
  63. bool nativeEventFilter(
  64. const QByteArray &eventType,
  65. void *message,
  66. native_event_filter_result *result) override;
  67. void processPostponedCalls(int level);
  68. void singleInstanceChecked();
  69. void launchApplication();
  70. void setupScreenScale();
  71. // Return window id for activation.
  72. uint64 execExternal(const QString &cmd);
  73. // Single instance application
  74. void socketConnected();
  75. void socketError(QLocalSocket::LocalSocketError e);
  76. void socketDisconnected();
  77. void socketWritten(qint64 bytes);
  78. void socketReading();
  79. void newInstanceConnected();
  80. void readClients();
  81. void removeClients();
  82. QEventLoopLocker _eventLoopLocker;
  83. const Qt::HANDLE _mainThreadId = nullptr;
  84. int _eventNestingLevel = 0;
  85. int _loopNestingLevel = 0;
  86. std::vector<int> _previousLoopNestingLevels;
  87. std::vector<PostponedCall> _postponedCalls;
  88. std::unique_ptr<Application> _application;
  89. QString _localServerName, _localSocketReadData;
  90. QLocalServer _localServer;
  91. QLocalSocket _localSocket;
  92. LocalClients _localClients;
  93. std::unique_ptr<QLockFile> _lockFile;
  94. bool _secondInstance = false;
  95. bool _started = false;
  96. static bool QuitOnStartRequested;
  97. std::unique_ptr<UpdateChecker> _updateChecker;
  98. QByteArray _lastCrashDump;
  99. MTP::ProxyData _sandboxProxy;
  100. rpl::event_stream<> _widgetUpdateRequests;
  101. std::unique_ptr<QThread> _deadlockDetector;
  102. };
  103. } // namespace Core