Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "VREventObserver.h"
8
9
#include "nsContentUtils.h"
10
#include "nsGlobalWindow.h"
11
12
#include "mozilla/Telemetry.h"
13
14
namespace mozilla {
15
namespace dom {
16
17
using namespace gfx;
18
19
/**
20
* This class is used by nsGlobalWindow to implement window.onvrdisplayactivate,
21
* window.onvrdisplaydeactivate, window.onvrdisplayconnected,
22
* window.onvrdisplaydisconnected, and window.onvrdisplaypresentchange.
23
*/
24
VREventObserver::VREventObserver(nsGlobalWindowInner* aGlobalWindow)
25
: mWindow(aGlobalWindow),
26
mIs2DView(true),
27
mHasReset(false),
28
mStopActivity(false) {
29
MOZ_ASSERT(aGlobalWindow);
30
31
UpdateSpentTimeIn2DTelemetry(false);
32
VRManagerChild* vmc = VRManagerChild::Get();
33
if (vmc) {
34
vmc->AddListener(this);
35
}
36
}
37
38
VREventObserver::~VREventObserver() { DisconnectFromOwner(); }
39
40
void VREventObserver::DisconnectFromOwner() {
41
// In the event that nsGlobalWindow is deallocated, VREventObserver may
42
// still be AddRef'ed elsewhere. Ensure that we don't UAF by
43
// dereferencing mWindow.
44
UpdateSpentTimeIn2DTelemetry(true);
45
mWindow = nullptr;
46
47
// Unregister from VRManagerChild
48
if (VRManagerChild::IsCreated()) {
49
VRManagerChild* vmc = VRManagerChild::Get();
50
vmc->RemoveListener(this);
51
}
52
mStopActivity = true;
53
}
54
55
void VREventObserver::UpdateSpentTimeIn2DTelemetry(bool aUpdate) {
56
// mHasReset for avoiding setting the telemetry continuously
57
// for the telemetry is already been set when it is at the background.
58
// then, it would be set again when the process is exit and calling
59
// VREventObserver::DisconnectFromOwner().
60
if (mWindow && mIs2DView && aUpdate && mHasReset) {
61
// The WebVR content is closed, and we will collect the telemetry info
62
// for the users who view it in 2D view only.
63
Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 0);
64
Telemetry::AccumulateTimeDelta(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_2D,
65
mSpendTimeIn2DView);
66
mHasReset = false;
67
} else if (!aUpdate) {
68
mSpendTimeIn2DView = TimeStamp::Now();
69
mHasReset = true;
70
}
71
}
72
73
void VREventObserver::StartActivity() {
74
mStopActivity = false;
75
VRManagerChild* vmc = VRManagerChild::Get();
76
vmc->StartActivity();
77
}
78
79
void VREventObserver::StopActivity() {
80
mStopActivity = true;
81
VRManagerChild* vmc = VRManagerChild::Get();
82
vmc->StopActivity();
83
}
84
85
bool VREventObserver::GetStopActivityStatus() const { return mStopActivity; }
86
87
void VREventObserver::NotifyAfterLoad() {
88
if (VRManagerChild::IsCreated()) {
89
VRManagerChild* vmc = VRManagerChild::Get();
90
vmc->FireDOMVRDisplayConnectEventsForLoad(this);
91
}
92
}
93
94
void VREventObserver::NotifyVRDisplayMounted(uint32_t aDisplayID) {
95
if (mWindow && mWindow->IsCurrentInnerWindow()) {
96
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
97
mWindow->DispatchVRDisplayActivate(aDisplayID,
98
VRDisplayEventReason::Mounted);
99
}
100
}
101
102
void VREventObserver::NotifyVRDisplayNavigation(uint32_t aDisplayID) {
103
if (mWindow && mWindow->IsCurrentInnerWindow()) {
104
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
105
mWindow->DispatchVRDisplayActivate(aDisplayID,
106
VRDisplayEventReason::Navigation);
107
}
108
}
109
110
void VREventObserver::NotifyVRDisplayRequested(uint32_t aDisplayID) {
111
if (mWindow && mWindow->IsCurrentInnerWindow()) {
112
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
113
mWindow->DispatchVRDisplayActivate(aDisplayID,
114
VRDisplayEventReason::Requested);
115
}
116
}
117
118
void VREventObserver::NotifyVRDisplayUnmounted(uint32_t aDisplayID) {
119
if (mWindow && mWindow->IsCurrentInnerWindow()) {
120
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
121
mWindow->DispatchVRDisplayDeactivate(aDisplayID,
122
VRDisplayEventReason::Unmounted);
123
}
124
}
125
126
void VREventObserver::NotifyVRDisplayConnect(uint32_t aDisplayID) {
127
/**
128
* We do not call nsGlobalWindow::NotifyActiveVRDisplaysChanged here, as we
129
* can assume that a newly enumerated display is not presenting WebVR
130
* content.
131
*/
132
if (mWindow && mWindow->IsCurrentInnerWindow()) {
133
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
134
mWindow->DispatchVRDisplayConnect(aDisplayID);
135
}
136
}
137
138
void VREventObserver::NotifyVRDisplayDisconnect(uint32_t aDisplayID) {
139
if (mWindow && mWindow->IsCurrentInnerWindow()) {
140
mWindow->NotifyActiveVRDisplaysChanged();
141
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
142
mWindow->DispatchVRDisplayDisconnect(aDisplayID);
143
}
144
}
145
146
void VREventObserver::NotifyVRDisplayPresentChange(uint32_t aDisplayID) {
147
// When switching to HMD present mode, it is no longer
148
// to be a 2D view.
149
mIs2DView = false;
150
151
if (mWindow && mWindow->IsCurrentInnerWindow()) {
152
mWindow->NotifyActiveVRDisplaysChanged();
153
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
154
mWindow->DispatchVRDisplayPresentChange(aDisplayID);
155
}
156
}
157
158
void VREventObserver::NotifyPresentationGenerationChanged(uint32_t aDisplayID) {
159
if (mWindow && mWindow->IsCurrentInnerWindow()) {
160
mWindow->NotifyPresentationGenerationChanged(aDisplayID);
161
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
162
}
163
}
164
165
void VREventObserver::NotifyEnumerationCompleted() {}
166
167
} // namespace dom
168
} // namespace mozilla