Bug 1900094 - Add telemetry for impressions missing due to domain-to-categories map...
[gecko.git] / netwerk / ipc / SocketProcessBridgeChild.cpp
blobdf4ee0e1775f9e578775c1ee66b9071ef4efe30f
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "SocketProcessBridgeChild.h"
7 #include "SocketProcessLogging.h"
9 #include "mozilla/AppShutdown.h"
10 #include "mozilla/Components.h"
11 #include "mozilla/dom/ContentChild.h"
12 #include "mozilla/ipc/BackgroundChild.h"
13 #include "mozilla/ipc/Endpoint.h"
14 #include "mozilla/net/NeckoChild.h"
15 #include "nsIObserverService.h"
16 #include "nsThreadUtils.h"
17 #include "mozilla/Preferences.h"
18 #include "mozilla/StaticPrefs_network.h"
20 namespace mozilla {
22 using dom::ContentChild;
24 namespace net {
26 StaticRefPtr<SocketProcessBridgeChild>
27 SocketProcessBridgeChild::sSocketProcessBridgeChild;
29 NS_IMPL_ISUPPORTS(SocketProcessBridgeChild, nsIObserver)
31 // static
32 bool SocketProcessBridgeChild::Create(
33 Endpoint<PSocketProcessBridgeChild>&& aEndpoint) {
34 MOZ_ASSERT(NS_IsMainThread());
36 sSocketProcessBridgeChild = new SocketProcessBridgeChild();
38 if (!aEndpoint.Bind(sSocketProcessBridgeChild)) {
39 MOZ_ASSERT(false, "Bind failed!");
40 sSocketProcessBridgeChild = nullptr;
41 return false;
44 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
45 if (os) {
46 os->AddObserver(sSocketProcessBridgeChild, "content-child-shutdown", false);
49 sSocketProcessBridgeChild->mSocketProcessPid = aEndpoint.OtherPid();
50 return true;
53 // static
54 already_AddRefed<SocketProcessBridgeChild>
55 SocketProcessBridgeChild::GetSingleton() {
56 RefPtr<SocketProcessBridgeChild> child = sSocketProcessBridgeChild;
57 return child.forget();
60 // static
61 RefPtr<SocketProcessBridgeChild::GetPromise>
62 SocketProcessBridgeChild::GetSocketProcessBridge() {
63 MOZ_ASSERT(NS_IsMainThread());
65 if (!StaticPrefs::network_process_enabled()) {
66 return GetPromise::CreateAndReject(nsCString("Socket process disabled!"),
67 __func__);
70 if (!gNeckoChild) {
71 return GetPromise::CreateAndReject(nsCString("No NeckoChild!"), __func__);
74 // ContentChild is shutting down, we should not try to create
75 // SocketProcessBridgeChild.
76 ContentChild* content = ContentChild::GetSingleton();
77 if (!content || content->IsShuttingDown()) {
78 return GetPromise::CreateAndReject(
79 nsCString("ContentChild is shutting down."), __func__);
82 if (sSocketProcessBridgeChild) {
83 return GetPromise::CreateAndResolve(sSocketProcessBridgeChild, __func__);
86 return gNeckoChild->SendInitSocketProcessBridge()->Then(
87 GetMainThreadSerialEventTarget(), __func__,
88 [](NeckoChild::InitSocketProcessBridgePromise::ResolveOrRejectValue&&
89 aResult) {
90 ContentChild* content = ContentChild::GetSingleton();
91 if (!content || content->IsShuttingDown()) {
92 return GetPromise::CreateAndReject(
93 nsCString("ContentChild is shutting down."), __func__);
95 if (!sSocketProcessBridgeChild) {
96 if (aResult.IsReject()) {
97 return GetPromise::CreateAndReject(
98 nsCString("SendInitSocketProcessBridge failed"), __func__);
101 if (!aResult.ResolveValue().IsValid()) {
102 return GetPromise::CreateAndReject(
103 nsCString(
104 "SendInitSocketProcessBridge resolved with an invalid "
105 "endpoint!"),
106 __func__);
109 if (!SocketProcessBridgeChild::Create(
110 std::move(aResult.ResolveValue()))) {
111 return GetPromise::CreateAndReject(
112 nsCString("SendInitSocketProcessBridge resolved with a valid "
113 "endpoint, "
114 "but SocketProcessBridgeChild::Create failed!"),
115 __func__);
119 return GetPromise::CreateAndResolve(sSocketProcessBridgeChild,
120 __func__);
124 SocketProcessBridgeChild::SocketProcessBridgeChild() : mShuttingDown(false) {
125 LOG(("CONSTRUCT SocketProcessBridgeChild::SocketProcessBridgeChild\n"));
128 SocketProcessBridgeChild::~SocketProcessBridgeChild() {
129 LOG(("DESTRUCT SocketProcessBridgeChild::SocketProcessBridgeChild\n"));
132 mozilla::ipc::IPCResult SocketProcessBridgeChild::RecvTest() {
133 LOG(("SocketProcessBridgeChild::RecvTest\n"));
134 return IPC_OK();
137 void SocketProcessBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
138 LOG(("SocketProcessBridgeChild::ActorDestroy\n"));
139 if (AbnormalShutdown == aWhy) {
140 if (gNeckoChild &&
141 !AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
142 // Let NeckoParent know that the socket process connections must be
143 // rebuilt.
144 gNeckoChild->SendResetSocketProcessBridge();
147 nsresult res;
148 nsCOMPtr<nsISerialEventTarget> mSTSThread;
149 mSTSThread = mozilla::components::SocketTransport::Service(&res);
150 if (NS_SUCCEEDED(res) && mSTSThread) {
151 // This must be called off the main thread. If we don't make this call
152 // ipc::BackgroundChild::GetOrCreateSocketActorForCurrentThread() will
153 // return the previous actor that is no longer able to send. This causes
154 // rebuilding the socket process connections to fail.
155 MOZ_ALWAYS_SUCCEEDS(mSTSThread->Dispatch(NS_NewRunnableFunction(
156 "net::SocketProcessBridgeChild::ActorDestroy",
157 []() { ipc::BackgroundChild::CloseForCurrentThread(); })));
161 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
162 if (os) {
163 os->RemoveObserver(this, "content-child-shutdown");
165 GetCurrentSerialEventTarget()->Dispatch(
166 NewRunnableMethod("net::SocketProcessBridgeChild::DeferredDestroy", this,
167 &SocketProcessBridgeChild::DeferredDestroy));
168 mShuttingDown = true;
171 NS_IMETHODIMP
172 SocketProcessBridgeChild::Observe(nsISupports* aSubject, const char* aTopic,
173 const char16_t* aData) {
174 if (!strcmp(aTopic, "content-child-shutdown")) {
175 PSocketProcessBridgeChild::Close();
177 return NS_OK;
180 void SocketProcessBridgeChild::DeferredDestroy() {
181 MOZ_ASSERT(NS_IsMainThread());
183 sSocketProcessBridgeChild = nullptr;
186 } // namespace net
187 } // namespace mozilla