From d799a20c7fd3c37e8c69e86d3dee4d5ab7c68018 Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Sat, 23 Aug 2014 02:15:36 +0300 Subject: [PATCH] Bug 786419 - Part 3 - Have the JS TCP sockets check if the app is offline r=jduell --- dom/network/TCPSocketParent.cpp | 48 ++++++++++++++++++++++++++++++++- dom/network/TCPSocketParent.h | 4 +++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/dom/network/TCPSocketParent.cpp b/dom/network/TCPSocketParent.cpp index 632cfc4cf5bb..56bb409b9305 100644 --- a/dom/network/TCPSocketParent.cpp +++ b/dom/network/TCPSocketParent.cpp @@ -68,14 +68,54 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPSocketParentBase) TCPSocketParentBase::TCPSocketParentBase() : mIPCOpen(false) { + mObserver = new mozilla::net::OfflineObserver(this); mozilla::HoldJSObjects(this); } TCPSocketParentBase::~TCPSocketParentBase() { + if (mObserver) { + mObserver->RemoveObserver(); + } mozilla::DropJSObjects(this); } +nsresult +TCPSocketParent::OfflineNotification(nsISupports *aSubject) +{ + nsCOMPtr info(do_QueryInterface(aSubject)); + if (!info) { + return NS_OK; + } + + uint32_t targetAppId = nsIScriptSecurityManager::UNKNOWN_APP_ID; + info->GetAppId(&targetAppId); + + // Obtain App ID + uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID; + const PContentParent *content = Manager()->Manager(); + const InfallibleTArray& browsers = content->ManagedPBrowserParent(); + if (browsers.Length() > 0) { + TabParent *tab = static_cast(browsers[0]); + appId = tab->OwnAppId(); + } + + if (appId != targetAppId) { + return NS_OK; + } + + // If the app is offline, close the socket + if (mSocket && NS_IsAppOffline(appId)) { + mSocket->Close(); + mSocket = nullptr; + mIntermediaryObj = nullptr; + mIntermediary = nullptr; + } + + return NS_OK; +} + + void TCPSocketParentBase::ReleaseIPDLReference() { @@ -115,7 +155,7 @@ TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bo } // Obtain App ID - uint32_t appId = nsIScriptSecurityManager::NO_APP_ID; + uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID; const PContentParent *content = Manager()->Manager(); const InfallibleTArray& browsers = content->ManagedPBrowserParent(); if (browsers.Length() > 0) { @@ -123,6 +163,12 @@ TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bo appId = tab->OwnAppId(); } + if (NS_IsAppOffline(appId)) { + NS_ERROR("Can't open socket because app is offline"); + FireInteralError(this, __LINE__); + return true; + } + nsresult rv; mIntermediary = do_CreateInstance("@mozilla.org/tcp-socket-intermediary;1", &rv); if (NS_FAILED(rv)) { diff --git a/dom/network/TCPSocketParent.h b/dom/network/TCPSocketParent.h index 778938a18b4a..01a87c78a78a 100644 --- a/dom/network/TCPSocketParent.h +++ b/dom/network/TCPSocketParent.h @@ -11,6 +11,7 @@ #include "nsCOMPtr.h" #include "nsIDOMTCPSocket.h" #include "js/TypeDecls.h" +#include "mozilla/net/OfflineObserver.h" #define TCPSOCKETPARENT_CID \ { 0x4e7246c6, 0xa8b3, 0x426d, { 0x9c, 0x17, 0x76, 0xda, 0xb1, 0xe1, 0xe1, 0x4a } } @@ -21,6 +22,7 @@ namespace dom { class PBrowserParent; class TCPSocketParentBase : public nsITCPSocketParent + , public mozilla::net::DisconnectableParent { public: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TCPSocketParentBase) @@ -36,6 +38,7 @@ protected: JS::Heap mIntermediaryObj; nsCOMPtr mIntermediary; nsCOMPtr mSocket; + nsRefPtr mObserver; bool mIPCOpen; }; @@ -58,6 +61,7 @@ public: virtual bool RecvData(const SendableData& aData, const uint32_t& aTrackingNumber) MOZ_OVERRIDE; virtual bool RecvRequestDelete() MOZ_OVERRIDE; + virtual nsresult OfflineNotification(nsISupports *) MOZ_OVERRIDE; private: virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;