Bug 786419 - Part 3 - Have the JS TCP sockets check if the app is offline r=jduell
--- a/dom/network/TCPSocketParent.cpp
+++ b/dom/network/TCPSocketParent.cpp
@@ -63,24 +63,64 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPSocketParentBase)
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<nsIAppOfflineInfo> 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<PBrowserParent*>& browsers = content->ManagedPBrowserParent();
+ if (browsers.Length() > 0) {
+ TabParent *tab = static_cast<TabParent*>(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()
{
MOZ_ASSERT(mIPCOpen);
mIPCOpen = false;
this->Release();
}
@@ -110,24 +150,30 @@ TCPSocketParent::RecvOpen(const nsString
// tests without this loophole.
if (net::UsingNeckoIPCSecurity() &&
!AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) {
FireInteralError(this, __LINE__);
return true;
}
// Obtain App ID
- uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
+ uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID;
const PContentParent *content = Manager()->Manager();
const InfallibleTArray<PBrowserParent*>& browsers = content->ManagedPBrowserParent();
if (browsers.Length() > 0) {
TabParent *tab = static_cast<TabParent*>(browsers[0]);
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)) {
FireInteralError(this, __LINE__);
return true;
}
rv = mIntermediary->Open(this, aHost, aPort, aUseSSL, aBinaryType, appId,
--- a/dom/network/TCPSocketParent.h
+++ b/dom/network/TCPSocketParent.h
@@ -6,41 +6,44 @@
#define mozilla_dom_TCPSocketParent_h
#include "mozilla/net/PTCPSocketParent.h"
#include "nsITCPSocketParent.h"
#include "nsCycleCollectionParticipant.h"
#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 } }
namespace mozilla {
namespace dom {
class PBrowserParent;
class TCPSocketParentBase : public nsITCPSocketParent
+ , public mozilla::net::DisconnectableParent
{
public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TCPSocketParentBase)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
void AddIPDLReference();
void ReleaseIPDLReference();
protected:
TCPSocketParentBase();
virtual ~TCPSocketParentBase();
JS::Heap<JSObject*> mIntermediaryObj;
nsCOMPtr<nsITCPSocketIntermediary> mIntermediary;
nsCOMPtr<nsIDOMTCPSocket> mSocket;
+ nsRefPtr<mozilla::net::OfflineObserver> mObserver;
bool mIPCOpen;
};
class TCPSocketParent : public mozilla::net::PTCPSocketParent
, public TCPSocketParentBase
{
public:
NS_DECL_NSITCPSOCKETPARENT
@@ -53,16 +56,17 @@ public:
virtual bool RecvStartTLS() MOZ_OVERRIDE;
virtual bool RecvSuspend() MOZ_OVERRIDE;
virtual bool RecvResume() MOZ_OVERRIDE;
virtual bool RecvClose() MOZ_OVERRIDE;
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;
};
} // namespace dom
} // namespace mozilla