mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1603539 - Part 2: Sending telemetry via VR shared memory. r=kip,thomasmo,chutten
Differential Revision: https://phabricator.services.mozilla.com/D57378 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
47d9630fe9
commit
f61dc99e7b
@ -261,6 +261,13 @@ void VRManager::UpdateRequestedDevices() {
|
||||
* at the VR display's native refresh rate.
|
||||
**/
|
||||
void VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp) {
|
||||
#if defined(XP_WIN) && defined(NIGHTLY_BUILD)
|
||||
// For Firefox Reality PC telemetry only.
|
||||
if (PR_GetEnv("MOZ_FXR")) {
|
||||
ProcessTelemetryEvent();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mState != VRManagerState::Active) {
|
||||
return;
|
||||
}
|
||||
@ -420,6 +427,37 @@ void VRManager::Run100msTasks() {
|
||||
CheckForShutdown();
|
||||
}
|
||||
|
||||
void VRManager::ProcessTelemetryEvent() {
|
||||
mozilla::gfx::VRShMem shmem(nullptr, true /*aRequiresMutex*/);
|
||||
MOZ_ASSERT(!shmem.HasExternalShmem());
|
||||
if (shmem.JoinShMem()) {
|
||||
mozilla::gfx::VRTelemetryState telemetryState = {0};
|
||||
shmem.PullTelemetryState(telemetryState);
|
||||
|
||||
if (telemetryState.uid != 0) {
|
||||
if (telemetryState.installedFrom) {
|
||||
MOZ_ASSERT(telemetryState.installedFromValue <= 0x07,
|
||||
"VRTelemetryId::INSTALLED_FROM only allows 3 bits.");
|
||||
Telemetry::Accumulate(Telemetry::FXRPC_FF_INSTALLATION_FROM,
|
||||
telemetryState.installedFromValue);
|
||||
}
|
||||
if (telemetryState.entryMethod) {
|
||||
MOZ_ASSERT(telemetryState.entryMethodValue <= 0x07,
|
||||
"VRTelemetryId::ENTRY_METHOD only allows 3 bits.");
|
||||
Telemetry::Accumulate(Telemetry::FXRPC_ENTRY_METHOD,
|
||||
telemetryState.entryMethodValue);
|
||||
}
|
||||
if (telemetryState.firstRun) {
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::FXRPC_ISFIRSTRUN,
|
||||
telemetryState.firstRunValue);
|
||||
}
|
||||
|
||||
telemetryState = {0};
|
||||
shmem.PushTelemetryState(telemetryState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VRManager::CheckForInactiveTimeout() {
|
||||
// Shut down the VR devices when not in use
|
||||
if (mVRDisplaysRequested || mVRDisplaysRequestedNonFocus ||
|
||||
|
@ -83,6 +83,7 @@ class VRManager : nsIObserver {
|
||||
uint32_t GetOptimalTaskInterval();
|
||||
void PullState(const std::function<bool()>& aWaitCondition = nullptr);
|
||||
void PushState(const bool aNotifyCond = false);
|
||||
void ProcessTelemetryEvent();
|
||||
static uint32_t AllocateDisplayID();
|
||||
|
||||
void DispatchVRDisplayInfoUpdate();
|
||||
|
@ -629,6 +629,7 @@ void VRShMem::PushWindowState(VRWindowState& aState) {
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
|
||||
void VRShMem::PullWindowState(VRWindowState& aState) {
|
||||
#if defined(XP_WIN)
|
||||
if (!mExternalShmem) {
|
||||
@ -645,6 +646,37 @@ void VRShMem::PullWindowState(VRWindowState& aState) {
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
|
||||
void VRShMem::PushTelemetryState(VRTelemetryState& aState) {
|
||||
#if defined(XP_WIN)
|
||||
if (!mExternalShmem) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool status = true;
|
||||
WaitForMutex lock(mMutex);
|
||||
status = lock.GetStatus();
|
||||
if (status) {
|
||||
memcpy((void*)&(mExternalShmem->telemetryState), (void*)&aState,
|
||||
sizeof(VRTelemetryState));
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
void VRShMem::PullTelemetryState(VRTelemetryState& aState) {
|
||||
#if defined(XP_WIN)
|
||||
if (!mExternalShmem) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool status = true;
|
||||
WaitForMutex lock(mMutex);
|
||||
status = lock.GetStatus();
|
||||
if (status) {
|
||||
memcpy((void*)&aState, (void*)&(mExternalShmem->telemetryState),
|
||||
sizeof(VRTelemetryState));
|
||||
}
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
|
||||
void VRShMem::SendEvent(uint64_t aWindowID,
|
||||
mozilla::gfx::VRFxEventType aEventType,
|
||||
mozilla::gfx::VRFxEventState aEventState) {
|
||||
|
@ -46,6 +46,9 @@ class VRShMem final {
|
||||
void PushWindowState(VRWindowState& aState);
|
||||
void PullWindowState(VRWindowState& aState);
|
||||
|
||||
void PushTelemetryState(VRTelemetryState& aState);
|
||||
void PullTelemetryState(VRTelemetryState& aState);
|
||||
|
||||
void SendIMEState(uint64_t aWindowID, mozilla::gfx::VRFxEventState aImeState);
|
||||
void SendFullscreenState(uint64_t aWindowID, bool aFullscreen);
|
||||
void SendShutdowmState(uint64_t aWindowID);
|
||||
|
@ -47,8 +47,8 @@ namespace gfx {
|
||||
// and mapped files if we have both release and nightlies
|
||||
// running at the same time? Or...what if we have multiple
|
||||
// release builds running on same machine? (Bug 1563232)
|
||||
#define SHMEM_VERSION "0.0.6"
|
||||
static const int32_t kVRExternalVersion = 13;
|
||||
#define SHMEM_VERSION "0.0.7"
|
||||
static const int32_t kVRExternalVersion = 14;
|
||||
|
||||
// We assign VR presentations to groups with a bitmask.
|
||||
// Currently, we will only display either content or chrome.
|
||||
@ -543,6 +543,41 @@ struct VRWindowState {
|
||||
char signalName[32];
|
||||
};
|
||||
|
||||
enum class VRTelemetryId : uint8_t {
|
||||
NONE = 0,
|
||||
INSTALLED_FROM = 1,
|
||||
ENTRY_METHOD = 2,
|
||||
FIRST_RUN = 3,
|
||||
TOTAL = 4,
|
||||
};
|
||||
|
||||
enum class VRTelemetryInstallFrom: uint8_t {
|
||||
User = 0,
|
||||
FxR = 1,
|
||||
HTC = 2,
|
||||
Valve = 3,
|
||||
TOTAL = 4,
|
||||
};
|
||||
|
||||
enum class VRTelemetryEntryMethod: uint8_t {
|
||||
SystemBtn = 0,
|
||||
Library = 1,
|
||||
Gaze = 2,
|
||||
TOTAL = 3,
|
||||
};
|
||||
|
||||
struct VRTelemetryState {
|
||||
uint32_t uid;
|
||||
|
||||
bool installedFrom : 1;
|
||||
bool entryMethod : 1;
|
||||
bool firstRun : 1;
|
||||
|
||||
uint8_t installedFromValue : 3;
|
||||
uint8_t entryMethodValue : 3;
|
||||
bool firstRunValue : 1;
|
||||
};
|
||||
|
||||
struct VRExternalShmem {
|
||||
int32_t version;
|
||||
int32_t size;
|
||||
@ -570,6 +605,7 @@ struct VRExternalShmem {
|
||||
#endif // !defined(__ANDROID__)
|
||||
#if defined(XP_WIN)
|
||||
VRWindowState windowState;
|
||||
VRTelemetryState telemetryState;
|
||||
#endif
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
void Clear() volatile {
|
||||
|
@ -12,3 +12,4 @@ EXPORTS
|
||||
CloseVRWindow PRIVATE
|
||||
SendUIMessageToVRWindow PRIVATE
|
||||
WaitForVREvent PRIVATE
|
||||
SendVRTelemetry PRIVATE
|
@ -13,9 +13,21 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <random>
|
||||
#include <queue>
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
class VRShmemInstance {
|
||||
public:
|
||||
VRShmemInstance() = delete;
|
||||
VRShmemInstance(const VRShmemInstance& aRHS) = delete;
|
||||
|
||||
static mozilla::gfx::VRShMem& GetInstance() {
|
||||
static mozilla::gfx::VRShMem shmem(nullptr, true /*aRequiresMutex*/);
|
||||
return shmem;
|
||||
}
|
||||
};
|
||||
|
||||
// VRWindowManager adds a level of indirection so that system HWND isn't exposed
|
||||
// outside of these APIs
|
||||
class VRWindowManager {
|
||||
@ -85,6 +97,62 @@ class VRWindowManager {
|
||||
};
|
||||
VRWindowManager* VRWindowManager::Instance = nullptr;
|
||||
|
||||
class VRTelemetryManager {
|
||||
public:
|
||||
void SendTelemetry(uint32_t aTelemetryId, uint32_t aValue) {
|
||||
if (!aTelemetryId) {
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::gfx::VRTelemetryState telemetryState = {0};
|
||||
VRShmemInstance::GetInstance().PullTelemetryState(telemetryState);
|
||||
|
||||
if (telemetryState.uid == 0) {
|
||||
telemetryState.uid = sUid;
|
||||
}
|
||||
|
||||
switch (mozilla::gfx::VRTelemetryId(aTelemetryId)) {
|
||||
case mozilla::gfx::VRTelemetryId::INSTALLED_FROM:
|
||||
MOZ_ASSERT(aValue <= 0x07,
|
||||
"VRTelemetryId::INSTALLED_FROM only allows 3 bits.");
|
||||
telemetryState.installedFrom = true;
|
||||
telemetryState.installedFromValue = aValue;
|
||||
break;
|
||||
case mozilla::gfx::VRTelemetryId::ENTRY_METHOD:
|
||||
MOZ_ASSERT(aValue <= 0x07,
|
||||
"VRTelemetryId::ENTRY_METHOD only allows 3 bits.");
|
||||
telemetryState.entryMethod = true;
|
||||
telemetryState.entryMethodValue = aValue;
|
||||
break;
|
||||
case mozilla::gfx::VRTelemetryId::FIRST_RUN:
|
||||
MOZ_ASSERT(aValue <= 0x01,
|
||||
"VRTelemetryId::FIRST_RUN only allows 1 bit.");
|
||||
telemetryState.firstRun = true;
|
||||
telemetryState.firstRunValue = aValue;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Undefined VR telemetry type.");
|
||||
break;
|
||||
}
|
||||
VRShmemInstance::GetInstance().PushTelemetryState(telemetryState);
|
||||
++sUid;
|
||||
}
|
||||
|
||||
static VRTelemetryManager* GetManager() {
|
||||
if (Instance == nullptr) {
|
||||
Instance = new VRTelemetryManager();
|
||||
}
|
||||
return Instance;
|
||||
}
|
||||
|
||||
private:
|
||||
static VRTelemetryManager* Instance;
|
||||
static uint32_t sUid; // It starts from 1, Zero means the data is read yet
|
||||
// from VRManager.
|
||||
};
|
||||
uint32_t VRTelemetryManager::sUid = 1;
|
||||
VRTelemetryManager* VRTelemetryManager::Instance = nullptr;
|
||||
|
||||
// Struct to send params to StartFirefoxThreadProc
|
||||
struct StartFirefoxParams {
|
||||
char* firefoxFolder;
|
||||
@ -130,17 +198,6 @@ DWORD StartFirefoxThreadProc(_In_ LPVOID lpParameter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
class VRShmemInstance {
|
||||
public:
|
||||
VRShmemInstance() = delete;
|
||||
VRShmemInstance(const VRShmemInstance& aRHS) = delete;
|
||||
|
||||
static mozilla::gfx::VRShMem& GetInstance() {
|
||||
static mozilla::gfx::VRShMem shmem(nullptr, true /*aRequiresMutex*/);
|
||||
return shmem;
|
||||
}
|
||||
};
|
||||
|
||||
// This export is responsible for starting up a new VR window in Firefox and
|
||||
// returning data related to its creation back to the caller.
|
||||
// See nsFxrCommandLineHandler::Handle for more details about the bootstrapping
|
||||
@ -305,4 +362,13 @@ void SendUIMessageToVRWindow(uint32_t nVRWindowID, uint32_t msg,
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendVRTelemetry(uint32_t nVRWindowID, uint32_t telemetryId,
|
||||
uint32_t value) {
|
||||
HWND hwnd = VRWindowManager::GetManager()->GetHWND(nVRWindowID);
|
||||
if (hwnd == nullptr) {
|
||||
return;
|
||||
}
|
||||
VRTelemetryManager::GetManager()->SendTelemetry(telemetryId, value);
|
||||
}
|
@ -28,3 +28,6 @@ typedef void (*PFN_SENDUIMSG)(uint32_t nVRWindowID, uint32_t msg,
|
||||
|
||||
typedef void (*PFN_WAITFORVREVENT)(uint32_t& nVRWindowID, uint32_t& eventType,
|
||||
uint32_t& eventData1, uint32_t& eventData2);
|
||||
|
||||
typedef void (*PFN_SENDVRTELEMETRY)(uint32_t nVRWindowID, uint32_t telemetryId,
|
||||
uint32_t value);
|
@ -14,6 +14,7 @@ EXPORTS
|
||||
CloseVRWindow PRIVATE
|
||||
SendUIMessageToVRWindow PRIVATE
|
||||
WaitForVREvent PRIVATE
|
||||
SendVRTelemetry PRIVATE
|
||||
|
||||
;+= Exports only available in Nightlies for testing
|
||||
SampleExport PRIVATE
|
||||
|
Loading…
Reference in New Issue
Block a user