Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/vr/ipc/VRProcessParent.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 "VRProcessParent.h"
8
#include "VRGPUChild.h"
9
#include "VRProcessManager.h"
10
#include "mozilla/gfx/GPUProcessManager.h"
11
#include "mozilla/gfx/GPUChild.h"
12
#include "mozilla/ipc/ProtocolTypes.h"
13
#include "mozilla/ipc/ProtocolUtils.h"       // for IToplevelProtocol
14
#include "mozilla/TimeStamp.h"               // for TimeStamp
15
#include "mozilla/Unused.h"
16
#include "VRChild.h"
17
#include "VRManager.h"
18
#include "VRThread.h"
19
#include "gfxVRPuppet.h"
20
21
#include "nsAppRunner.h"                  // for IToplevelProtocol
22
#include "mozilla/ipc/ProtocolUtils.h"
23
24
using std::vector;
25
using std::string;
26
27
using namespace mozilla::ipc;
28
29
namespace mozilla {
30
namespace gfx {
31
32
VRProcessParent::VRProcessParent()
33
  : GeckoChildProcessHost(GeckoProcessType_VR),
34
    mTaskFactory(this),
35
    mChannelClosed(false)
36
0
{
37
0
  MOZ_COUNT_CTOR(VRProcessParent);
38
0
}
39
40
VRProcessParent::~VRProcessParent()
41
0
{
42
0
  // Cancel all tasks. We don't want anything triggering after our caller
43
0
  // expects this to go away.
44
0
  {
45
0
    MonitorAutoLock lock(mMonitor);
46
0
    mTaskFactory.RevokeAll();
47
0
  }
48
0
  MOZ_COUNT_DTOR(VRProcessParent);
49
0
}
50
51
bool
52
VRProcessParent::Launch()
53
0
{
54
0
  mLaunchThread = NS_GetCurrentThread();
55
0
56
0
  std::vector<std::string> extraArgs;
57
0
  nsCString parentBuildID(mozilla::PlatformBuildID());
58
0
  extraArgs.push_back("-parentBuildID");
59
0
  extraArgs.push_back(parentBuildID.get());
60
0
61
0
  if (!GeckoChildProcessHost::AsyncLaunch(extraArgs)) {
62
0
    return false;
63
0
  }
64
0
  return true;
65
0
}
66
67
void
68
VRProcessParent::Shutdown()
69
0
{
70
0
  if (mVRChild) {
71
0
    // The channel might already be closed if we got here unexpectedly.
72
0
    if (!mChannelClosed) {
73
0
      mVRChild->Close();
74
0
    }
75
0
76
0
#ifndef NS_FREE_PERMANENT_DATA
77
0
    // No need to communicate shutdown, the VR process doesn't need to
78
0
    // communicate anything back.
79
0
    KillHard("NormalShutdown");
80
0
#endif
81
0
82
0
    // If we're shutting down unexpectedly, we're in the middle of handling an
83
0
    // ActorDestroy for PGPUChild, which is still on the stack. We'll return
84
0
    // back to OnChannelClosed.
85
0
    //
86
0
    // Otherwise, we'll wait for OnChannelClose to be called whenever PGPUChild
87
0
    // acknowledges shutdown.
88
0
    return;
89
0
  }
90
0
91
0
  DestroyProcess();
92
0
}
93
94
static void
95
DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
96
0
{
97
0
  XRE_GetIOMessageLoop()->
98
0
    PostTask(mozilla::MakeAndAddRef<DeleteTask<GeckoChildProcessHost>>(aSubprocess));
99
0
}
100
101
102
void
103
VRProcessParent::DestroyProcess()
104
0
{
105
0
  mLaunchThread->Dispatch(NewRunnableFunction("DestroyProcessRunnable", DelayedDeleteSubprocess, this));
106
0
}
107
108
void
109
VRProcessParent::InitAfterConnect(bool aSucceeded)
110
0
{
111
0
  if (aSucceeded) {
112
0
    mVRChild = MakeUnique<VRChild>(this);
113
0
114
0
    DebugOnly<bool> rv =
115
0
      mVRChild->Open(GetChannel(), base::GetProcId(GetChildProcessHandle()));
116
0
    MOZ_ASSERT(rv);
117
0
118
0
    mVRChild->Init();
119
0
120
0
    // Make vr-gpu process connection
121
0
    GPUChild* gpuChild = GPUProcessManager::Get()->GetGPUChild();
122
0
    MOZ_ASSERT(gpuChild);
123
0
124
0
    Endpoint<PVRGPUChild> vrGPUBridge;
125
0
    VRProcessManager* vpm = VRProcessManager::Get();
126
0
    DebugOnly<bool> opened = vpm->CreateGPUBridges(gpuChild->OtherPid(), &vrGPUBridge);
127
0
    MOZ_ASSERT(opened);
128
0
129
0
    Unused << gpuChild->SendInitVR(std::move(vrGPUBridge));
130
0
  }
131
0
}
132
133
void
134
VRProcessParent::KillHard(const char* aReason)
135
0
{
136
0
  ProcessHandle handle = GetChildProcessHandle();
137
0
  if (!base::KillProcess(handle, base::PROCESS_END_KILLED_BY_USER, false)) {
138
0
    NS_WARNING("failed to kill subprocess!");
139
0
  }
140
0
141
0
  SetAlreadyDead();
142
0
}
143
144
void
145
VRProcessParent::OnChannelError()
146
0
{
147
0
  MOZ_ASSERT(false, "VR process channel error.");
148
0
}
149
150
void
151
VRProcessParent::OnChannelConnected(int32_t peer_pid)
152
0
{
153
0
  MOZ_ASSERT(!NS_IsMainThread());
154
0
155
0
  GeckoChildProcessHost::OnChannelConnected(peer_pid);
156
0
157
0
  // Post a task to the main thread. Take the lock because mTaskFactory is not
158
0
  // thread-safe.
159
0
  RefPtr<Runnable> runnable;
160
0
  {
161
0
    MonitorAutoLock lock(mMonitor);
162
0
    runnable = mTaskFactory.NewRunnableMethod(&VRProcessParent::OnChannelConnectedTask);
163
0
  }
164
0
  NS_DispatchToMainThread(runnable);
165
0
}
166
167
void
168
VRProcessParent::OnChannelConnectedTask()
169
0
{
170
0
  InitAfterConnect(true);
171
0
}
172
173
void
174
VRProcessParent::OnChannelErrorTask()
175
0
{
176
0
  MOZ_ASSERT(false, "VR process channel error.");
177
0
}
178
179
void
180
VRProcessParent::OnChannelClosed()
181
0
{
182
0
  mChannelClosed = true;
183
0
  DestroyProcess();
184
0
185
0
  // Release the actor.
186
0
  VRChild::Destroy(std::move(mVRChild));
187
0
  MOZ_ASSERT(!mVRChild);
188
0
}
189
190
base::ProcessId
191
VRProcessParent::OtherPid()
192
0
{
193
0
  return mVRChild->OtherPid();
194
0
}
195
196
} // namespace gfx
197
} // namespace mozilla