Skip to content

Commit

Permalink
Bug 1603539 - Part 2: Sending telemetry via VR shared memory. r=kip,t…
Browse files Browse the repository at this point in the history
…homasmo,chutten

Differential Revision: https://phabricator.services.mozilla.com/D57378

--HG--
extra : moz-landing-system : lando
  • Loading branch information
daoshengmu committed Dec 23, 2019
1 parent 47d9630 commit f61dc99
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 13 deletions.
38 changes: 38 additions & 0 deletions gfx/vr/VRManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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 ||
Expand Down
1 change: 1 addition & 0 deletions gfx/vr/VRManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
32 changes: 32 additions & 0 deletions gfx/vr/VRShMem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ void VRShMem::PushWindowState(VRWindowState& aState) {
}
#endif // defined(XP_WIN)
}

void VRShMem::PullWindowState(VRWindowState& aState) {
#if defined(XP_WIN)
if (!mExternalShmem) {
Expand All @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions gfx/vr/VRShMem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
40 changes: 38 additions & 2 deletions gfx/vr/external_api/moz_external_vr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions gfx/vr/vrhost/vrhost.def
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ EXPORTS
CloseVRWindow PRIVATE
SendUIMessageToVRWindow PRIVATE
WaitForVREvent PRIVATE
SendVRTelemetry PRIVATE
88 changes: 77 additions & 11 deletions gfx/vr/vrhost/vrhostapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
3 changes: 3 additions & 0 deletions gfx/vr/vrhost/vrhostex.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
1 change: 1 addition & 0 deletions gfx/vr/vrhost/vrhostnightly.def
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ EXPORTS
CloseVRWindow PRIVATE
SendUIMessageToVRWindow PRIVATE
WaitForVREvent PRIVATE
SendVRTelemetry PRIVATE

;+= Exports only available in Nightlies for testing
SampleExport PRIVATE
Expand Down

0 comments on commit f61dc99

Please sign in to comment.