Bug 950660: Part 3 - make TCPSocket/TCPSocketChild interface an IDL interface r=jdm

This commit is contained in:
Randell Jesup 2015-09-20 23:05:20 -04:00
parent e364ba4dcc
commit a6a383f835
6 changed files with 105 additions and 43 deletions

View File

@ -143,6 +143,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TCPSocket)
NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsITCPSocketCallback)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
TCPSocket::TCPSocket(nsIGlobalObject* aGlobal, const nsAString& aHost, uint16_t aPort,
@ -460,12 +461,12 @@ TCPSocket::ActivateTLS()
}
}
void
NS_IMETHODIMP
TCPSocket::FireErrorEvent(const nsAString& aName, const nsAString& aType)
{
if (mSocketBridgeParent) {
mSocketBridgeParent->FireErrorEvent(aName, aType, mReadyState);
return;
return NS_OK;
}
TCPSocketErrorEventInit init;
@ -476,30 +477,32 @@ TCPSocket::FireErrorEvent(const nsAString& aName, const nsAString& aType)
nsRefPtr<TCPSocketErrorEvent> event =
TCPSocketErrorEvent::Constructor(this, NS_LITERAL_STRING("error"), init);
MOZ_ASSERT(event);
event->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
return NS_OK;
}
void
NS_IMETHODIMP
TCPSocket::FireEvent(const nsAString& aType)
{
if (mSocketBridgeParent) {
mSocketBridgeParent->FireEvent(aType, mReadyState);
return;
return NS_OK;
}
AutoJSAPI api;
if (NS_WARN_IF(!api.Init(GetOwner()))) {
return;
return NS_ERROR_FAILURE;
}
JS::Rooted<JS::Value> val(api.cx());
FireDataEvent(api.cx(), aType, val);
return FireDataEvent(api.cx(), aType, val);
}
void
TCPSocket::FireDataEvent(const nsAString& aType,
const InfallibleTArray<uint8_t>& buffer)
NS_IMETHODIMP
TCPSocket::FireDataArrayEvent(const nsAString& aType,
const InfallibleTArray<uint8_t>& buffer)
{
AutoJSAPI api;
if (NS_WARN_IF(!api.Init(GetOwner()))) {
@ -510,13 +513,14 @@ TCPSocket::FireDataEvent(const nsAString& aType,
bool ok = IPC::DeserializeArrayBuffer(cx, buffer, &val);
if (ok) {
FireDataEvent(aType, val);
return FireDataEvent(cx, aType, val);
}
return NS_ERROR_FAILURE;
}
void
TCPSocket::FireDataEvent(const nsAString& aType,
const nsACString& aString)
NS_IMETHODIMP
TCPSocket::FireDataStringEvent(const nsAString& aType,
const nsACString& aString)
{
AutoJSAPI api;
if (NS_WARN_IF(!api.Init(GetOwner()))) {
@ -527,11 +531,12 @@ TCPSocket::FireDataEvent(const nsAString& aType,
bool ok = ToJSValue(cx, NS_ConvertASCIItoUTF16(aString), &val);
if (ok) {
FireDataEvent(aType, val);
return FireDataEvent(cx, aType, val);
}
return NS_ERROR_FAILURE;
}
void
NS_IMETHODIMP
TCPSocket::FireDataEvent(JSContext* aCx, const nsAString& aType, JS::Handle<JS::Value> aData)
{
MOZ_ASSERT(!mSocketBridgeParent);
@ -546,6 +551,7 @@ TCPSocket::FireDataEvent(JSContext* aCx, const nsAString& aType, JS::Handle<JS::
event->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
return NS_OK;
}
JSObject*
@ -733,11 +739,10 @@ TCPSocket::MaybeReportErrorAndCloseIfOpen(nsresult status) {
}
}
FireErrorEvent(errName, errorType);
NS_WARN_IF(NS_FAILED(FireErrorEvent(errName, errorType)));
}
FireEvent(NS_LITERAL_STRING("close"));
return NS_OK;
return FireEvent(NS_LITERAL_STRING("close"));
}
void
@ -1105,26 +1110,28 @@ TCPSocket::SetAppIdAndBrowser(uint32_t aAppId, bool aInBrowser)
#endif
}
void
NS_IMETHODIMP
TCPSocket::UpdateReadyState(uint32_t aReadyState)
{
MOZ_ASSERT(mSocketBridgeChild);
mReadyState = static_cast<TCPReadyState>(aReadyState);
return NS_OK;
}
void
NS_IMETHODIMP
TCPSocket::UpdateBufferedAmount(uint32_t aBufferedAmount, uint32_t aTrackingNumber)
{
if (aTrackingNumber != mTrackingNumber) {
return;
return NS_OK;
}
mBufferedAmount = aBufferedAmount;
if (!mBufferedAmount) {
if (mWaitingForDrain) {
mWaitingForDrain = false;
FireEvent(NS_LITERAL_STRING("drain"));
return FireEvent(NS_LITERAL_STRING("drain"));
}
}
return NS_OK;
}
#ifdef MOZ_WIDGET_GONK

View File

@ -14,6 +14,7 @@
#include "nsISupportsImpl.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsITCPSocketCallback.h"
#include "js/RootingAPI.h"
class nsISocketTransport;
@ -72,6 +73,7 @@ class TCPSocket final : public DOMEventTargetHelper
, public nsIInputStreamCallback
, public nsIObserver
, public nsSupportsWeakReference
, public nsITCPSocketCallback
{
public:
TCPSocket(nsIGlobalObject* aGlobal, const nsAString& aHost, uint16_t aPort,
@ -84,6 +86,7 @@ public:
NS_DECL_NSITRANSPORTEVENTSINK
NS_DECL_NSIINPUTSTREAMCALLBACK
NS_DECL_NSIOBSERVER
NS_DECL_NSITCPSOCKETCALLBACK
nsPIDOMWindow* GetParentObject() const
{
@ -154,20 +157,6 @@ public:
// Inform this socket that a buffered send() has completed sending.
void NotifyCopyComplete(nsresult aStatus);
// Set this child socket's number of buffered bytes, based on the count from the parent
// process associated with the given sequence id.
void UpdateBufferedAmount(uint32_t aAmount, uint32_t aTrackingNumber);
// Set this child socket's ready state, based on the state in the parent process.
void UpdateReadyState(uint32_t aReadyState);
// Dispatch an "error" event at this object.
void FireErrorEvent(const nsAString& aName, const nsAString& aMessage);
// Dispatch an event of the given type at this object.
void FireEvent(const nsAString& aType);
// Dispatch a "data" event at this object.
void FireDataEvent(const nsAString& aType, const InfallibleTArray<uint8_t>& buffer);
void FireDataEvent(const nsAString& aType, const nsAString& aString);
void FireDataEvent(JSContext* aCx, const nsAString& aType, JS::Handle<JS::Value> aData);
// Initialize this socket from a low-level connection that hasn't connected yet
// (called from RecvOpenBind() in TCPSocketParent).
nsresult InitWithUnconnectedTransport(nsISocketTransport* aTransport);

View File

@ -11,6 +11,7 @@
#include "mozilla/net/NeckoChild.h"
#include "mozilla/dom/PBrowserChild.h"
#include "mozilla/dom/TabChild.h"
#include "nsITCPSocketCallback.h"
#include "TCPSocket.h"
#include "nsContentUtils.h"
#include "jsapi.h"
@ -93,7 +94,7 @@ TCPSocketChild::TCPSocketChild(const nsAString& aHost, const uint16_t& aPort)
}
void
TCPSocketChild::SendOpen(TCPSocket* aSocket, bool aUseSSL, bool aUseArrayBuffers)
TCPSocketChild::SendOpen(nsITCPSocketCallback* aSocket, bool aUseSSL, bool aUseArrayBuffers)
{
mSocket = aSocket;
@ -103,7 +104,7 @@ TCPSocketChild::SendOpen(TCPSocket* aSocket, bool aUseSSL, bool aUseArrayBuffers
}
void
TCPSocketChild::SendWindowlessOpenBind(TCPSocket* aSocket,
TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
bool aUseSSL)
@ -164,9 +165,9 @@ TCPSocketChild::RecvCallback(const nsString& aType,
const SendableData& data = aData.get_SendableData();
if (data.type() == SendableData::TArrayOfuint8_t) {
mSocket->FireDataEvent(cx, aType, data.get_ArrayOfuint8_t());
mSocket->FireDataArrayEvent(aType, data.get_ArrayOfuint8_t());
} else if (data.type() == SendableData::TnsCString) {
mSocket->FireDataEvent(aType, data.get_nsCString());
mSocket->FireDataStringEvent(aType, data.get_nsCString());
} else {
MOZ_CRASH("Invalid callback data type!");
}

View File

@ -12,6 +12,8 @@
#include "nsCOMPtr.h"
#include "js/TypeDecls.h"
class nsITCPSocketCallback;
namespace IPC {
bool
DeserializeArrayBuffer(JSContext* cx,
@ -36,7 +38,7 @@ protected:
TCPSocketChildBase();
virtual ~TCPSocketChildBase();
nsRefPtr<TCPSocket> mSocket;
nsCOMPtr<nsITCPSocketCallback> mSocket;
bool mIPCOpen;
};
@ -49,8 +51,8 @@ public:
TCPSocketChild(const nsAString& aHost, const uint16_t& aPort);
~TCPSocketChild();
void SendOpen(TCPSocket* aSocket, bool aUseSSL, bool aUseArrayBuffers);
void SendWindowlessOpenBind(TCPSocket* aSocket,
void SendOpen(nsITCPSocketCallback* aSocket, bool aUseSSL, bool aUseArrayBuffers);
void SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
const nsACString& aRemoteHost, uint16_t aRemotePort,
const nsACString& aLocalHost, uint16_t aLocalPort,
bool aUseSSL);

View File

@ -6,6 +6,7 @@
XPIDL_SOURCES += [
'nsIMozNavigatorNetwork.idl',
'nsITCPSocketCallback.idl',
'nsIUDPSocketChild.idl',
]

View File

@ -0,0 +1,62 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* MozTCPSocket exposes a TCP client and server sockets
* to highly privileged apps. It provides a buffered, non-blocking
* interface for sending. For receiving, it uses an asynchronous,
* event handler based interface.
*/
#include "domstubs.idl"
%{C++
template<class T> class InfallibleTArray;
%}
[ref] native nsUint8TArrayRef(InfallibleTArray<uint8_t>);
[ptr] native JSContextPtr(JSContext);
/*
* This interface is implemented in TCPSocket.cpp as an internal interface
* for use in cross-process socket implementation.
* Needed to account for multiple possible types that can be provided to
* the socket callbacks as arguments.
*/
[scriptable, uuid(ac2c4b69-cb79-4767-b1ce-bcf62945cd39)]
interface nsITCPSocketCallback : nsISupports {
// Limitation of TCPSocket's buffer size.
const unsigned long BUFFER_SIZE = 65536;
// Dispatch an "error" event at this object with the given name and type.
void fireErrorEvent(in AString name, in AString type);
// Dispatch a "data" event at this object with a string
void fireDataStringEvent(in DOMString type, in ACString data);
// Dispatch a "data" event at this object with an Array
void fireDataArrayEvent(in DOMString type, [const] in nsUint8TArrayRef data);
// Dispatch a "data" event at this object with an ArrayBuffer argument
void fireDataEvent(in JSContextPtr cx, in DOMString type, in jsval data);
// Dispatch an event of the given type at this object.
void fireEvent(in DOMString type);
// Update the DOM object's readyState.
// @param readyState
// new ready state
void updateReadyState(in unsigned long readystate);
// Update the DOM object's bufferedAmount value with a tracking number to
// to allow tracking of which writes are "in-flight"
// @param bufferedAmount
// TCPSocket parent's bufferedAmount.
// @param trackingNumber
// A number to ensure the bufferedAmount is updated after data
// from child are sent to parent.
void updateBufferedAmount(in uint32_t bufferedAmount,
in uint32_t trackingNumber);
};