diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 41654dfe6e..e7bccae892 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -195,6 +195,7 @@ static const QString FBX_EXTENSION = ".fbx"; static const QString OBJ_EXTENSION = ".obj"; static const QString AVA_JSON_EXTENSION = ".ava.json"; +static const int MSECS_PER_SEC = 1000; static const int MIRROR_VIEW_TOP_PADDING = 5; static const int MIRROR_VIEW_LEFT_PADDING = 10; static const int MIRROR_VIEW_WIDTH = 265; @@ -365,7 +366,7 @@ bool setupEssentials(int& argc, char** argv) { Setting::preInit(); - CrashHandler::checkForAndHandleCrash(); + bool previousSessionCrashed = CrashHandler::checkForAndHandleCrash(); CrashHandler::writeRunningMarkerFiler(); qAddPostRoutine(CrashHandler::deleteRunningMarkerFile); @@ -427,7 +428,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(true, qApp, qApp); DependencyManager::set(); - return true; + return previousSessionCrashed; } // FIXME move to header, or better yet, design some kind of UI manager @@ -448,10 +449,13 @@ PluginContainer* _pluginContainer; OffscreenGLCanvas* _chromiumShareContext { nullptr }; Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context); +Setting::Handle sessionRunTime{ "sessionRunTime", 0 }; + Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : QApplication(argc, argv), _window(new MainWindow(desktop())), - _dependencyManagerIsSetup(setupEssentials(argc, argv)), + _sessionRunTimer(startupTimer), + _previousSessionCrashed(setupEssentials(argc, argv)), _undoStackScriptingInterface(&_undoStack), _frameCount(0), _fps(60.0f), @@ -601,7 +605,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(clearDomainOctreeDetails())); // update our location every 5 seconds in the metaverse server, assuming that we are authenticated with one - const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * 1000; + const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * MSECS_PER_SEC; auto discoverabilityManager = DependencyManager::get(); connect(&locationUpdateTimer, &QTimer::timeout, discoverabilityManager.data(), &DiscoverabilityManager::updateLocation); @@ -623,7 +627,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // connect to appropriate slots on AccountManager AccountManager& accountManager = AccountManager::getInstance(); - const qint64 BALANCE_UPDATE_INTERVAL_MSECS = 5 * 1000; + const qint64 BALANCE_UPDATE_INTERVAL_MSECS = 5 * MSECS_PER_SEC; connect(&balanceUpdateTimer, &QTimer::timeout, &accountManager, &AccountManager::updateBalance); balanceUpdateTimer.start(BALANCE_UPDATE_INTERVAL_MSECS); @@ -638,7 +642,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : accountManager.setIsAgent(true); accountManager.setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL); - UserActivityLogger::getInstance().launch(applicationVersion()); + // sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value. + // The value will be 0 if the user blew away settings this session, which is both a feature and a bug. + UserActivityLogger::getInstance().launch(applicationVersion(), _previousSessionCrashed, sessionRunTime.get()); // once the event loop has started, check and signal for an access token QMetaObject::invokeMethod(&accountManager, "checkAndSignalForAccessToken", Qt::QueuedConnection); @@ -2804,6 +2810,7 @@ bool Application::exportEntities(const QString& filename, float x, float y, floa void Application::loadSettings() { + sessionRunTime.set(0); // Just clean living. We're about to saveSettings, which will update value. DependencyManager::get()->loadSettings(); DependencyManager::get()->loadSettings(); @@ -2817,6 +2824,7 @@ void Application::loadSettings() { } void Application::saveSettings() { + sessionRunTime.set(_sessionRunTimer.elapsed() / MSECS_PER_SEC); DependencyManager::get()->saveSettings(); DependencyManager::get()->saveSettings(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 3b906a7d17..695d30998a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -377,8 +377,9 @@ private: void maybeToggleMenuVisible(QMouseEvent* event); MainWindow* _window; + QElapsedTimer& _sessionRunTimer; - bool _dependencyManagerIsSetup; + bool _previousSessionCrashed; OffscreenGLCanvas* _offscreenContext { nullptr }; DisplayPluginPointer _displayPlugin; diff --git a/interface/src/CrashHandler.cpp b/interface/src/CrashHandler.cpp index 5a194973b4..50cca15c88 100644 --- a/interface/src/CrashHandler.cpp +++ b/interface/src/CrashHandler.cpp @@ -27,7 +27,7 @@ static const QString RUNNING_MARKER_FILENAME = "Interface.running"; -void CrashHandler::checkForAndHandleCrash() { +bool CrashHandler::checkForAndHandleCrash() { QFile runningMarkerFile(runningMarkerFilePath()); if (runningMarkerFile.exists()) { QSettings::setDefaultFormat(QSettings::IniFormat); @@ -42,7 +42,9 @@ void CrashHandler::checkForAndHandleCrash() { handleCrash(action); } } + return true; } + return false; } CrashHandler::Action CrashHandler::promptUserForAction() { diff --git a/interface/src/CrashHandler.h b/interface/src/CrashHandler.h index 61361b6107..18c935b595 100644 --- a/interface/src/CrashHandler.h +++ b/interface/src/CrashHandler.h @@ -17,7 +17,7 @@ class CrashHandler { public: - static void checkForAndHandleCrash(); + static bool checkForAndHandleCrash(); static void writeRunningMarkerFiler(); static void deleteRunningMarkerFile(); diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index f2019ba9a9..2e74a5166c 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -78,11 +78,15 @@ void UserActivityLogger::requestError(QNetworkReply& errorReply) { qCDebug(networking) << errorReply.error() << "-" << errorReply.errorString(); } -void UserActivityLogger::launch(QString applicationVersion) { +void UserActivityLogger::launch(QString applicationVersion, bool previousSessionCrashed, int previousSessionRuntime) { const QString ACTION_NAME = "launch"; QJsonObject actionDetails; QString VERSION_KEY = "version"; + QString CRASH_KEY = "previousSessionCrashed"; + QString RUNTIME_KEY = "previousSessionRuntime"; actionDetails.insert(VERSION_KEY, applicationVersion); + actionDetails.insert(CRASH_KEY, previousSessionCrashed); + actionDetails.insert(RUNTIME_KEY, previousSessionRuntime); logAction(ACTION_NAME, actionDetails); } diff --git a/libraries/networking/src/UserActivityLogger.h b/libraries/networking/src/UserActivityLogger.h index 2811be86a8..8eda086521 100644 --- a/libraries/networking/src/UserActivityLogger.h +++ b/libraries/networking/src/UserActivityLogger.h @@ -29,7 +29,7 @@ public slots: void disable(bool disable); void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters()); - void launch(QString applicationVersion); + void launch(QString applicationVersion, bool previousSessionCrashed, int previousSessionRuntime); void changedDisplayName(QString displayName); void changedModel(QString typeOfModel, QString modelURL);