History

Merge branch 'master' of https://github.com/highfidelity/hifi into vive-ui

howard-stearns committed 10 years ago

Commit 67f76db2 parents dc34181 a48cce237 files · +431 −51Browse files

Showing the changes to interface/src/Application.cpp (1 of 37 files). Show all

Unified · Split

interface/src/Application.cpp+127−5
@@ -68,6 +68,7 @@ · 67 unmodified lines
6868 #include <input-plugins/InputPlugin.h>
6969 #include <controllers/UserInputMapper.h>
7070 #include <controllers/StateController.h>
71+#include <UserActivityLoggerScriptingInterface.h>
7172 #include <LogHandler.h>
7273 #include <MainWindow.h>
7374 #include <MessagesClient.h>
@@ -150,6 +151,8 @@ · 76 unmodified lines
150151 #include "InterfaceParentFinder.h"
151152
152153 #include "FrameTimingsScriptingInterface.h"
154+#include <GPUIdent.h>
155+#include <gl/GLHelpers.h>
153156
154157 // On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
155158 // FIXME seems to be broken.
@@ -437,7 +440,7 @@ bool setupEssentials(int& argc, char** argv) { · 281 unmodified lines
437440 DependencyManager::set<HMDScriptingInterface>();
438441 DependencyManager::set<ResourceScriptingInterface>();
439442 DependencyManager::set<ToolbarScriptingInterface>();
440−
443+ DependencyManager::set<UserActivityLoggerScriptingInterface>();
441444
442445 #if defined(Q_OS_MAC) || defined(Q_OS_WIN)
443446 DependencyManager::set<SpeechRecognizer>();
@@ -675,10 +678,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 231 unmodified lines
675678 accountManager->setIsAgent(true);
676679 accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL);
677680
678− // sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
679− // The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
680− UserActivityLogger::getInstance().launch(applicationVersion(), _previousSessionCrashed, sessionRunTime.get());
681−
682681 auto addressManager = DependencyManager::get<AddressManager>();
683682
684683 // use our MyAvatar position and quat for address manager path
@@ -768,6 +767,39 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 83 unmodified lines
768767 // Make sure we don't time out during slow operations at startup
769768 updateHeartbeat();
770769
770+
771+ // sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
772+ // The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
773+ auto gpuIdent = GPUIdent::getInstance();
774+ auto glContextData = getGLContextData();
775+ QJsonObject properties = {
776+ { "previousSessionCrashed", _previousSessionCrashed },
777+ { "previousSessionRuntime", sessionRunTime.get() },
778+ { "cpu_architecture", QSysInfo::currentCpuArchitecture() },
779+ { "kernel_type", QSysInfo::kernelType() },
780+ { "kernel_version", QSysInfo::kernelVersion() },
781+ { "os_type", QSysInfo::productType() },
782+ { "os_version", QSysInfo::productVersion() },
783+ { "gpu_name", gpuIdent->getName() },
784+ { "gpu_driver", gpuIdent->getDriver() },
785+ { "gpu_memory", static_cast<qint64>(gpuIdent->getMemory()) },
786+ { "gl_version_int", glVersionToInteger(glContextData.value("version").toString()) },
787+ { "gl_version", glContextData["version"] },
788+ { "gl_vender", glContextData["vendor"] },
789+ { "gl_sl_version", glContextData["slVersion"] },
790+ { "gl_renderer", glContextData["renderer"] }
791+ };
792+ auto macVersion = QSysInfo::macVersion();
793+ if (macVersion != QSysInfo::MV_None) {
794+ properties["os_osx_version"] = QSysInfo::macVersion();
795+ }
796+ auto windowsVersion = QSysInfo::windowsVersion();
797+ if (windowsVersion != QSysInfo::WV_None) {
798+ properties["os_win_version"] = QSysInfo::windowsVersion();
799+ }
800+ UserActivityLogger::getInstance().logAction("launch", properties);
801+
802+
771803 // Tell our entity edit sender about our known jurisdictions
772804 _entityEditSender.setServerJurisdictions(&_entityServerJurisdictions);
773805 _entityEditSender.setMyAvatar(getMyAvatar());
@@ -1063,6 +1095,89 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : · 289 unmodified lines
10631095 }
10641096 });
10651097
1098+ // Add periodic checks to send user activity data
1099+ static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000;
1100+ static int SEND_STATS_INTERVAL_MS = 10000;
1101+ static int NEARBY_AVATAR_RADIUS_METERS = 10;
1102+
1103+ // Periodically send fps as a user activity event
1104+ QTimer* sendStatsTimer = new QTimer(this);
1105+ sendStatsTimer->setInterval(SEND_STATS_INTERVAL_MS);
1106+ connect(sendStatsTimer, &QTimer::timeout, this, [this]() {
1107+ QJsonObject properties = {};
1108+ MemoryInfo memInfo;
1109+ if (getMemoryInfo(memInfo)) {
1110+ properties["system_memory_total"] = static_cast<qint64>(memInfo.totalMemoryBytes);
1111+ properties["system_memory_used"] = static_cast<qint64>(memInfo.usedMemoryBytes);
1112+ properties["process_memory_used"] = static_cast<qint64>(memInfo.processUsedMemoryBytes);
1113+ }
1114+
1115+ auto displayPlugin = qApp->getActiveDisplayPlugin();
1116+
1117+ properties["fps"] = _frameCounter.rate();
1118+ properties["present_rate"] = displayPlugin->presentRate();
1119+ properties["new_frame_present_rate"] = displayPlugin->newFramePresentRate();
1120+ properties["dropped_frame_rate"] = displayPlugin->droppedFrameRate();
1121+ properties["sim_rate"] = getAverageSimsPerSecond();
1122+ properties["avatar_sim_rate"] = getAvatarSimrate();
1123+
1124+ auto bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
1125+ properties["packet_rate_in"] = bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond();
1126+ properties["packet_rate_out"] = bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond();
1127+ properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond();
1128+ properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond();
1129+
1130+ auto nodeList = DependencyManager::get<NodeList>();
1131+ SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer);
1132+ SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
1133+ SharedNodePointer avatarMixerNode = nodeList->soloNodeOfType(NodeType::AvatarMixer);
1134+ SharedNodePointer assetServerNode = nodeList->soloNodeOfType(NodeType::AssetServer);
1135+ SharedNodePointer messagesMixerNode = nodeList->soloNodeOfType(NodeType::MessagesMixer);
1136+ properties["entity_ping"] = entityServerNode ? entityServerNode->getPingMs() : -1;
1137+ properties["audio_ping"] = audioMixerNode ? audioMixerNode->getPingMs() : -1;
1138+ properties["avatar_ping"] = avatarMixerNode ? avatarMixerNode->getPingMs() : -1;
1139+ properties["asset_ping"] = assetServerNode ? assetServerNode->getPingMs() : -1;
1140+ properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1;
1141+
1142+ auto loadingRequests = ResourceCache::getLoadingRequests();
1143+ properties["active_downloads"] = loadingRequests.size();
1144+ properties["pending_downloads"] = ResourceCache::getPendingRequestCount();
1145+
1146+ properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false;
1147+
1148+ UserActivityLogger::getInstance().logAction("stats", properties);
1149+ });
1150+ sendStatsTimer->start();
1151+
1152+
1153+ // Periodically check for count of nearby avatars
1154+ static int lastCountOfNearbyAvatars = -1;
1155+ QTimer* checkNearbyAvatarsTimer = new QTimer(this);
1156+ checkNearbyAvatarsTimer->setInterval(CHECK_NEARBY_AVATARS_INTERVAL_MS);
1157+ connect(checkNearbyAvatarsTimer, &QTimer::timeout, this, [this]() {
1158+ auto avatarManager = DependencyManager::get<AvatarManager>();
1159+ int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getPosition(),
1160+ NEARBY_AVATAR_RADIUS_METERS) - 1;
1161+ if (nearbyAvatars != lastCountOfNearbyAvatars) {
1162+ lastCountOfNearbyAvatars = nearbyAvatars;
1163+ UserActivityLogger::getInstance().logAction("nearby_avatars", { { "count", nearbyAvatars } });
1164+ }
1165+ });
1166+ checkNearbyAvatarsTimer->start();
1167+
1168+ // Track user activity event when we receive a mute packet
1169+ auto onMutedByMixer = []() {
1170+ UserActivityLogger::getInstance().logAction("received_mute_packet");
1171+ };
1172+ connect(DependencyManager::get<AudioClient>().data(), &AudioClient::mutedByMixer, this, onMutedByMixer);
1173+
1174+ // Track when the address bar is opened
1175+ auto onAddressBarToggled = [this]() {
1176+ // Record time
1177+ UserActivityLogger::getInstance().logAction("opened_address_bar", { { "uptime_ms", _sessionRunTimer.elapsed() } });
1178+ };
1179+ connect(DependencyManager::get<DialogsManager>().data(), &DialogsManager::addressBarToggled, this, onAddressBarToggled);
1180+
10661181 // Make sure we don't time out during slow operations at startup
10671182 updateHeartbeat();
10681183
@@ -4578,6 +4693,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 3509 unmodified lines
45784693
45794694 scriptEngine->registerGlobalObject("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data());
45804695 scriptEngine->registerGlobalObject("Reticle", getApplicationCompositor().getReticleInterface());
4696+
4697+ scriptEngine->registerGlobalObject("UserActivityLogger", DependencyManager::get<UserActivityLoggerScriptingInterface>().data());
45814698 }
45824699
45834700 bool Application::canAcceptURL(const QString& urlString) const {
@@ -5180,6 +5297,11 @@ void Application::updateDisplayMode() { · 596 unmodified lines
51805297 return;
51815298 }
51825299
5300+ UserActivityLogger::getInstance().logAction("changed_display_mode", {
5301+ { "previous_display_mode", _displayPlugin ? _displayPlugin->getName() : "" },
5302+ { "display_mode", newDisplayPlugin ? newDisplayPlugin->getName() : "" }
5303+ });
5304+
51835305 auto offscreenUi = DependencyManager::get<OffscreenUi>();
51845306
51855307 // Make the switch atomic from the perspective of other threads