Bug 1513057 - P4: Update online/offline status to socket process r=dragana,mayhemer

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kershaw Chang 2019-01-11 13:29:21 +00:00
parent 07a7cc19a1
commit 078fff139b
7 changed files with 102 additions and 3 deletions

View File

@ -1530,7 +1530,7 @@ nsIOService::GetManageOfflineStatus(bool *aManage) {
// input argument 'data' is already UTF8'ed
nsresult nsIOService::OnNetworkLinkEvent(const char *data) {
if (IsNeckoChild()) {
if (IsNeckoChild() || IsSocketProcessChild()) {
// There is nothing IO service could do on the child process
// with this at the moment. Feel free to add functionality
// here at will, though.

View File

@ -95,6 +95,11 @@ inline bool IsNeckoChild() {
return amChild;
}
inline bool IsSocketProcessChild() {
static bool amChild = (XRE_GetProcessType() == GeckoProcessType_Socket);
return amChild;
}
namespace NeckoCommonInternal {
extern bool gSecurityDisabled;
extern bool gRegisteredBool;

View File

@ -24,6 +24,7 @@ child:
bool anonymize,
bool minimizeMemoryUsage,
MaybeFileDesc DMDFile);
async SetOffline(bool offline);
};
} // namespace net

View File

@ -106,5 +106,17 @@ mozilla::ipc::IPCResult SocketProcessChild::RecvRequestMemoryReport(
return IPC_OK();
}
mozilla::ipc::IPCResult SocketProcessChild::RecvSetOffline(
const bool& aOffline) {
LOG(("SocketProcessChild::RecvSetOffline aOffline=%d\n", aOffline));
nsCOMPtr<nsIIOService> io(do_GetIOService());
NS_ASSERTION(io, "IO Service can not be null");
io->SetOffline(aOffline);
return IPC_OK();
}
} // namespace net
} // namespace mozilla

View File

@ -29,6 +29,7 @@ class SocketProcessChild final : public PSocketProcessChild {
mozilla::ipc::IPCResult RecvRequestMemoryReport(
const uint32_t& generation, const bool& anonymize,
const bool& minimizeMemoryUsage, const MaybeFileDesc& DMDFile) override;
mozilla::ipc::IPCResult RecvSetOffline(const bool& aOffline) override;
void CleanUp();

View File

@ -4,12 +4,67 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SocketProcessHost.h"
#include "SocketProcessParent.h"
#include "nsAppRunner.h"
#include "nsIObserverService.h"
#include "SocketProcessParent.h"
namespace mozilla {
namespace net {
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
class OfflineObserver final : public nsIObserver {
public:
NS_DECL_THREADSAFE_ISUPPORTS
explicit OfflineObserver(SocketProcessHost* aProcessHost)
: mProcessHost(aProcessHost) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->AddObserver(this, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC, false);
}
}
void Destroy() {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(this, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC);
}
mProcessHost = nullptr;
}
private:
// nsIObserver implementation.
NS_IMETHOD
Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) override {
if (!mProcessHost) {
return NS_OK;
}
if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
NS_ConvertUTF16toUTF8 dataStr(aData);
const char* offline = dataStr.get();
if (!mProcessHost->IsConnected() ||
mProcessHost->GetActor()->SendSetOffline(
!strcmp(offline, "true") ? true : false)) {
return NS_ERROR_NOT_AVAILABLE;
}
}
return NS_OK;
}
virtual ~OfflineObserver() = default;
SocketProcessHost* mProcessHost;
};
NS_IMPL_ISUPPORTS(OfflineObserver, nsIObserver)
SocketProcessHost::SocketProcessHost(Listener* aListener)
: GeckoChildProcessHost(GeckoProcessType_Socket),
mListener(aListener),
@ -21,7 +76,15 @@ SocketProcessHost::SocketProcessHost(Listener* aListener)
MOZ_COUNT_CTOR(SocketProcessHost);
}
SocketProcessHost::~SocketProcessHost() { MOZ_COUNT_DTOR(SocketProcessHost); }
SocketProcessHost::~SocketProcessHost() {
MOZ_COUNT_DTOR(SocketProcessHost);
if (mOfflineObserver) {
RefPtr<OfflineObserver> observer = mOfflineObserver;
NS_DispatchToMainThread(
NS_NewRunnableFunction("SocketProcessHost::DestroyOfflineObserver",
[observer]() { observer->Destroy(); }));
}
}
bool SocketProcessHost::Launch() {
MOZ_ASSERT(mLaunchPhase == LaunchPhase::Unlaunched);
@ -143,6 +206,16 @@ void SocketProcessHost::InitAfterConnect(bool aSucceeded) {
DebugOnly<bool> rv = mSocketProcessParent->Open(
GetChannel(), base::GetProcId(GetChildProcessHandle()));
MOZ_ASSERT(rv);
nsCOMPtr<nsIIOService> ioService(do_GetIOService());
MOZ_ASSERT(ioService, "No IO service?");
bool offline = false;
DebugOnly<nsresult> result = ioService->GetOffline(&offline);
MOZ_ASSERT(NS_SUCCEEDED(result), "Failed getting offline?");
Unused << GetActor()->SendSetOffline(offline);
mOfflineObserver = new OfflineObserver(this);
}
if (mListener) {
@ -155,6 +228,10 @@ void SocketProcessHost::Shutdown() {
MOZ_ASSERT(NS_IsMainThread());
mListener = nullptr;
if (mOfflineObserver) {
mOfflineObserver->Destroy();
mOfflineObserver = nullptr;
}
if (mSocketProcessParent) {
// OnChannelClosed uses this to check if the shutdown was expected or

View File

@ -14,6 +14,7 @@
namespace mozilla {
namespace net {
class OfflineObserver;
class SocketProcessParent;
// SocketProcessHost is the "parent process" container for a subprocess handle
@ -101,6 +102,8 @@ class SocketProcessHost final : public mozilla::ipc::GeckoChildProcessHost {
// OnProcessUnexpectedShutdown will be invoked.
bool mShutdownRequested;
bool mChannelClosed;
RefPtr<OfflineObserver> mOfflineObserver;
};
class SocketProcessMemoryReporter : public MemoryReportingProcess {