Coverage Report

Created: 2018-09-25 14:53

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