swift
application.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2016 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_CORE_APPLICATION_H
7 #define SWIFT_CORE_APPLICATION_H
8 
9 #include <atomic>
10 #include <functional>
11 
12 #include <QByteArray>
13 #include <QCommandLineOption>
14 #include <QCommandLineParser>
15 #include <QList>
16 #include <QNetworkAccessManager>
17 #include <QObject>
18 #include <QReadWriteLock>
19 #include <QScopedPointer>
20 #include <QString>
21 #include <QStringList>
22 
24 #include "core/corefacadeconfig.h"
25 #include "core/data/globalsetup.h"
28 #include "core/inputmanager.h"
29 #include "core/swiftcoreexport.h"
30 #include "core/webreaderflags.h"
32 #include "misc/db/updateinfo.h"
33 #include "misc/identifiable.h"
35 #include "misc/network/url.h"
36 #include "misc/slot.h"
37 #include "misc/statusmessagelist.h"
38 
39 class QHttpMultiPart;
40 class QNetworkReply;
41 class QNetworkRequest;
42 
43 namespace swift::misc
44 {
45  class CFileLogger;
46  class CLogCategoryList;
47  namespace shared_state
48  {
49  class CDataLinkDBus;
50  }
51 } // namespace swift::misc
52 
53 namespace swift::core
54 {
55  class CCoreFacade;
56  class CCookieManager;
57  class CSetupReader;
58  class CWebDataServices;
59  class ISimulator;
60  namespace context
61  {
62  class IContextApplication;
63  class IContextAudio;
64  class CContextAudioBase;
65  class IContextNetwork;
66  class IContextOwnAircraft;
67  class IContextSimulator;
68  } // namespace context
69 
87  {
88  Q_OBJECT
89 
90  public:
92  static CApplication *instance();
93 
95  static const QStringList &getLogCategories();
96 
98  explicit CApplication(swift::misc::CApplicationInfo::Application application, bool init = true);
99 
101  explicit CApplication(
102  const QString &applicationName = executable(),
103  swift::misc::CApplicationInfo::Application application = swift::misc::CApplicationInfo::Unknown,
104  bool init = true);
105 
107  ~CApplication() override;
108 
110  static swift::misc::CApplicationInfoList getRunningApplications();
111 
113  static bool isApplicationRunning(swift::misc::CApplicationInfo::Application application);
114 
116  bool isAlreadyRunning() const;
117 
119  virtual void gracefulShutdown();
120 
123  bool isShuttingDown() const;
124 
127  bool isIncognito() const;
128 
131  void setIncognito(bool incognito);
132 
135  void toggleIncognito();
136 
138  const swift::misc::CApplicationInfo &getApplicationInfo() const { return m_applicationInfo; }
139 
141  const QString &getApplicationName() const { return m_applicationName; }
142 
144  const QString &getApplicationNameAndVersion() const;
145 
147  const QString &getApplicationNameVersionDetailed() const;
148 
151  data::CGlobalSetup getGlobalSetup() const;
152 
154  swift::misc::db::CUpdateInfo getUpdateInfo() const;
155 
157  void reloadUpdateInfo();
158 
161  swift::misc::db::CDistribution getOwnDistribution() const;
162 
164  const QString &versionStringDetailed() const;
165 
167  const QString &swiftVersionString() const;
168 
170  const char *swiftVersionChar();
171 
173  bool isDeveloperFlagSet() const { return m_devFlag; }
174 
176  QString getInfoString(const QString &separator) const;
177 
179  void restartApplication(const QStringList &newArguments = {}, const QStringList &removeArguments = {});
180 
182  int exec();
183 
185  static QString getTemporaryDirectory();
186 
189  static bool registerAsRunning();
190 
193  static bool unregisterAsRunning();
194 
196  static void exit(int retcode = EXIT_SUCCESS);
197 
202  static void processEventsFor(int milliseconds);
203 
206  static QStringList clearCaches();
207 
208  // ----------------------- settings -------------------------------
209 
211  bool hasUnsavedSettings() const;
212 
214  void saveSettingsOnShutdown(bool saveSettings);
215 
217  QStringList getUnsavedSettingsKeys() const;
218 
220  swift::misc::CStatusMessage saveSettingsByKey(const QStringList &keys);
221 
222  // ----------------------- cmd line args / parsing ----------------------------------------
223 
225  QStringList argumentsJoined(const QStringList &newArguments = {},
226  const QStringList &removeArguments = {}) const;
227 
229  static QStringList arguments();
230 
233 
235  bool addParserOption(const QCommandLineOption &option);
236 
238  bool addParserOptions(const QList<QCommandLineOption> &options);
239 
241  void addDBusAddressOption();
242 
244  QString getCmdDBusAddressValue() const;
245 
247  void addNetworkOptions();
248 
250  void addAudioOptions();
251 
253  bool skipSingleApplicationCheck() const;
254 
256  bool isParserOptionSet(const QString &option) const;
257 
259  bool isParserOptionSet(const QCommandLineOption &option) const;
260 
262  QString getParserValue(const QString &option) const;
263 
265  QString getParserValue(const QCommandLineOption &option) const;
266 
274  bool parseCommandLineArgsAndLoadSetup();
275 
277  virtual void cmdLineErrorMessage(const QString &text, const QString &informativeText) const;
278 
280  virtual void cmdLineErrorMessage(const swift::misc::CStatusMessageList &msgs) const;
281 
283 
286  void simulateCrash();
287 
290  void simulateAssert();
291 
294  void enableCrashDumpUpload(bool enable);
295 
297  bool isSupportingCrashpad() const;
298 
299  // ----------------------- Input ----------------------------------------
300 
302  CInputManager *getInputManager() const { return m_inputManager; }
303 
304  // ----------------------- simulator ----------------------------------------
305 
307  QPointer<ISimulator> getISimulator() const;
308 
310  bool hasSimulator() const;
311 
312  // ----------------------- contexts ----------------------------------------
313 
315  swift::misc::shared_state::CDataLinkDBus *getDataLinkDBus();
316 
319 
323  bool supportsContexts(bool ignoreShutdownTest = false) const;
324 
326  const CCoreFacadeConfig &getCoreFacadeConfig() const { return m_coreFacadeConfig; }
327 
331  swift::misc::CStatusMessageList initContextsAndStartCoreFacade(const CCoreFacadeConfig &coreConfig);
332 
336  swift::misc::CStatusMessageList startCoreFacadeWithoutContexts();
337 
342  initAndStartWebDataServices(CWebReaderFlags::WebReader webReader,
343  const db::CDatabaseReaderConfigList &dbReaderConfig);
344 
346  CCoreFacade *getCoreFacade() { return m_coreFacade.data(); }
347 
349  bool isLocalContext() const;
350 
352  bool isDBusContext() const;
353 
355  const CCoreFacade *getCoreFacade() const { return m_coreFacade.data(); }
356 
358 
361  const context::IContextNetwork *getIContextNetwork() const;
362  const context::IContextAudio *getIContextAudio() const;
363  const context::CContextAudioBase *getCContextAudioBase() const;
364  const context::IContextApplication *getIContextApplication() const;
365  const context::IContextOwnAircraft *getIContextOwnAircraft() const;
366  const context::IContextSimulator *getIContextSimulator() const;
367  context::IContextNetwork *getIContextNetwork();
368  context::IContextAudio *getIContextAudio();
369  context::CContextAudioBase *getCContextAudioBase();
370  context::IContextApplication *getIContextApplication();
371  context::IContextOwnAircraft *getIContextOwnAircraft();
372  context::IContextSimulator *getIContextSimulator();
374 
375  // ----------------------- setup data ---------------------------------
376 
378  virtual bool hasMinimumMappingVersion() const;
379 
381  bool hasSetupReader() const;
382 
385  CSetupReader *getSetupReader() const;
386 
388  bool isSetupAvailable() const;
389 
392  swift::misc::network::CUrl getVatsimMetarUrl() const;
393 
396  swift::misc::network::CUrl getVatsimDataFileUrl() const;
397 
399  swift::misc::network::CUrl getVatsimServerFileUrl() const;
400 
402  swift::misc::network::CUrl getVatsimFsdHttpUrl() const;
403 
405  virtual bool start();
406 
407  // ------------------------- network -----------------------------------------------
408 
411 
412  static constexpr int NoRedirects = -1;
413  static constexpr int NoLogRequestId = -1;
414  static constexpr int DefaultMaxRedirects = 2;
415 
417  using CallbackSlot = swift::misc::CSlot<void(QNetworkReply *)>;
418 
420  using ProgressSlot = swift::misc::CSlot<void(int, qint64, qint64, const QUrl &)>;
421 
423  void deleteAllCookies();
424 
427  const QNetworkAccessManager *getNetworkAccessManager() const { return m_accessManager; }
428 
431  QNetworkAccessManager *getNetworkAccessManager() { return m_accessManager; }
432 
435  bool hasWebDataServices() const;
436 
439  CWebDataServices *getWebDataServices() const;
440 
443  QNetworkReply *getFromNetwork(const swift::misc::network::CUrl &url, const CallbackSlot &callback,
444  int maxRedirects = DefaultMaxRedirects);
445 
448  QNetworkReply *getFromNetwork(const swift::misc::network::CUrl &url, const CallbackSlot &callback,
449  const ProgressSlot &progress, int maxRedirects = DefaultMaxRedirects);
450 
453  QNetworkReply *getFromNetwork(const swift::misc::network::CUrl &url, int logId, const CallbackSlot &callback,
454  const ProgressSlot &progress, int maxRedirects = DefaultMaxRedirects);
455 
458  QNetworkReply *getFromNetwork(const QNetworkRequest &request, const CallbackSlot &callback,
459  int maxRedirects = DefaultMaxRedirects);
460 
463  QNetworkReply *getFromNetwork(const QNetworkRequest &request, const CallbackSlot &callback,
464  const ProgressSlot &progress, int maxRedirects = DefaultMaxRedirects);
465 
468  QNetworkReply *getFromNetwork(const QNetworkRequest &request, int logId, const CallbackSlot &callback,
469  const ProgressSlot &progress, int maxRedirects = DefaultMaxRedirects);
470 
473  QNetworkReply *deleteResourceFromNetwork(const QNetworkRequest &request, int logId,
474  const CallbackSlot &callback, int maxRedirects = DefaultMaxRedirects);
475 
478  QNetworkReply *postToNetwork(const QNetworkRequest &request, int logId, const QByteArray &data,
479  const CallbackSlot &callback);
480 
484  QNetworkReply *postToNetwork(const QNetworkRequest &request, int logId, QHttpMultiPart *multiPart,
485  const CallbackSlot &callback);
486 
489  QNetworkReply *headerFromNetwork(const swift::misc::network::CUrl &url, const CallbackSlot &callback,
490  int maxRedirects = NoRedirects);
491 
494  QNetworkReply *headerFromNetwork(const QNetworkRequest &request, const CallbackSlot &callback,
495  int maxRedirects = NoRedirects);
496 
499  QNetworkReply *
500  downloadFromNetwork(const swift::misc::network::CUrl &url, const QString &saveAsFileName,
501  const swift::misc::CSlot<void(const swift::misc::CStatusMessage &)> &callback,
502  int maxRedirects = DefaultMaxRedirects);
504 
505  signals:
507  void updateInfoAvailable(bool success);
508 
511  void startUpCompleted(bool success);
512 
515 
517  void webDataServicesStarted(bool success);
518 
521 
522  protected:
524  virtual void displaySetupLoadFailure(swift::misc::CStatusMessageList msgs);
525 
527  virtual void onStartUpCompleted();
528 
530  void init(bool withMetadata);
531 
533  static int indexOfCommandLineOption(const QCommandLineOption &option,
534  const QStringList &args = CApplication::arguments());
535 
537  static void argumentsWithoutOption(const QCommandLineOption &option, QStringList &args);
538 
540  virtual bool parsingHookIn() { return true; }
541 
543  virtual void onCoreFacadeStarted();
544 
547 
549  bool isSet(const QCommandLineOption &option) const;
550 
553  swift::misc::CStatusMessageList startCoreFacade();
554 
557  swift::misc::CStatusMessageList startWebDataServices(CWebReaderFlags::WebReader webReader,
558  const db::CDatabaseReaderConfigList &dbReaderConfig);
559 
561  static const QString &executable();
562 
564  static void registerMetadata();
565 
566  // cmd parsing
567  QList<QCommandLineOption> m_allOptions;
568  QCommandLineParser m_parser;
569  QCommandLineOption m_cmdHelp { "help" };
570  QCommandLineOption m_cmdVersion { "version" };
571  QCommandLineOption m_cmdDBusAddress { "emptyDBus" };
572  QCommandLineOption m_cmdDevelopment { "dev" };
573  QCommandLineOption m_cmdClearCache { "clearcache" };
574  QCommandLineOption m_cmdTestCrashpad { "testcrashpad" };
575  QCommandLineOption m_cmdSkipSingleApp { "skipsa" };
576  bool m_parsed = false;
577  bool m_started = false;
578  bool m_alreadyRunning = false;
579  std::atomic_bool m_shutdown { false };
580  std::atomic_bool m_incognito { false };
581  std::atomic_bool m_shutdownInProgress { false };
582 
583  private:
586 
588  void cmdLineHelpMessage();
589 
591  void cmdLineVersionMessage();
592 
594  void initNetwork();
595 
597  void initLogging();
598 
600  void initParser();
601 
603  bool initIsRunningInDeveloperEnvironment() const;
604 
606  swift::misc::CStatusMessage initLocalSettings();
607 
608  using NetworkRequestOrPostFunction =
609  std::function<QNetworkReply *(QNetworkAccessManager &, const QNetworkRequest &)>;
610 
613  QNetworkReply *httpRequestImpl(const QNetworkRequest &request, int logId, const CallbackSlot &callback,
614  int maxRedirects, NetworkRequestOrPostFunction requestOrPostMethod);
615 
618  QNetworkReply *httpRequestImpl(const QNetworkRequest &request, int logId, const CallbackSlot &callback,
619  const ProgressSlot &progress, int maxRedirects,
620  NetworkRequestOrPostFunction getPostOrDeleteRequest);
621 
623  void httpRequestImplInQAMThread(const QNetworkRequest &request, int logId, const CallbackSlot &callback,
624  const ProgressSlot &progress, int maxRedirects,
625  NetworkRequestOrPostFunction getPostOrDeleteRequest);
626 
628  void tagApplicationDataDirectory();
629 
632  bool startupCheck() const;
633 
636  bool loadSetupAndHandleErrors();
637 
642  bool parseCommandLineArguments();
643 
644  CInputManager *m_inputManager = nullptr;
645  QNetworkAccessManager *m_accessManager = nullptr;
646  swift::misc::CApplicationInfo m_applicationInfo;
647  QScopedPointer<CCoreFacade> m_coreFacade;
648  QScopedPointer<CSetupReader> m_setupReader;
649  QScopedPointer<CGitHubPackagesReader> m_gitHubPackagesReader;
650  QScopedPointer<CWebDataServices> m_webDataServices;
651  QScopedPointer<swift::misc::CFileLogger> m_fileLogger;
652  QPointer<CCookieManager> m_cookieManager;
653  const QString m_applicationName;
654  QReadWriteLock m_accessManagerLock;
655  CCoreFacadeConfig m_coreFacadeConfig;
656  bool m_useContexts = false;
657  bool m_devFlag = false;
658  bool m_saveSettingsOnShutdown = true;
659  bool m_localSettingsLoaded = false;
660 
661  // -------------- crashpad -----------------
663  this, &CApplication::onCrashDumpUploadEnabledChanged
664  };
665 
667  void onCrashDumpUploadEnabledChanged();
668  };
669 } // namespace swift::core
670 
673 
674 #endif // SWIFT_CORE_APPLICATION_H
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
Definition: application.cpp:71
void aboutToShutdown()
About to shutdown.
CInputManager * getInputManager() const
The input manager, if available.
Definition: application.h:302
const QNetworkAccessManager * getNetworkAccessManager() const
Access to access manager.
Definition: application.h:427
bool isDeveloperFlagSet() const
Running with dev.flag?
Definition: application.h:173
QNetworkAccessManager * getNetworkAccessManager()
Access to access manager.
Definition: application.h:431
QCommandLineParser m_parser
cmd parser
Definition: application.h:568
void coreFacadeStarted()
Facade started.
QList< QCommandLineOption > m_allOptions
All registered options.
Definition: application.h:567
CCoreFacade * getCoreFacade()
Get the facade.
Definition: application.h:346
const QString & getApplicationName() const
Application name and version.
Definition: application.h:141
void updateInfoAvailable(bool success)
Update info available (cache, web load)
const CCoreFacadeConfig & getCoreFacadeConfig() const
The core facade config.
Definition: application.h:326
const CCoreFacade * getCoreFacade() const
Get the facade.
Definition: application.h:355
virtual swift::misc::CStatusMessageList startHookIn()
Can be used to start special services.
Definition: application.h:546
virtual bool parsingHookIn()
Can be used to parse specialized arguments.
Definition: application.h:540
void webDataServicesStarted(bool success)
Web data services started.
const swift::misc::CApplicationInfo & getApplicationInfo() const
swift application running
Definition: application.h:138
static QStringList arguments()
Similar to QCoreApplication::arguments.
void startUpCompleted(bool success)
Startup has been completed Will be triggered shortly before starting the event loop.
Configuration object for the contexts.
The class providing facades (the contexts) for all DBus relevant operations.
Definition: corefacade.h:57
Input manager handling hotkey function calls.
Definition: inputmanager.h:32
Read the central URLs / locations of our data, setup and versions.
Definition: setupreader.h:36
Encapsulates reading data from web sources.
Audio context interface.
Definition: contextaudio.h:61
Global settings for readers, debug flags, etc.
Definition: globalsetup.h:31
Value object encapsulating a list of reader configs.
Description of a swift application.
Application
Enumeration of application roles.
List of swift application descriptions.
Base class with a member CIdentifier to be inherited by a class which has an identity in the environm...
Definition: identifiable.h:24
Class template for accessing a specific value in the CSettingsCache.
Callable wrapper for a member function with function signature F.
Definition: slot.h:62
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
Distributions for channel.
Definition: distribution.h:27
Update info, i.e. artifacts and distributions.
Definition: updateinfo.h:24
Value object encapsulating information of a location, kind of simplified CValueObject compliant versi...
Definition: url.h:27
Backend services of the swift project, like dealing with the network or the simulators.
Definition: actionbind.cpp:7
void registerMetadata()
Register all relevant metadata in swift::core.
Free functions in swift::misc.
QString applicationName()
Get application name.
Definition: filelogger.cpp:23
#define SWIFT_CORE_EXPORT
Export a class or function from the library.