nsresult PresentationService::HandleSessionRequest( nsIPresentationSessionRequest* aRequest) { nsCOMPtr<nsIPresentationControlChannel> ctrlChannel; nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel)); if (NS_WARN_IF(NS_FAILED(rv) || !ctrlChannel)) { return rv; } nsAutoString url; rv = aRequest->GetUrl(url); if (NS_WARN_IF(NS_FAILED(rv))) { ctrlChannel->Disconnect(rv); return rv; } nsAutoString sessionId; rv = aRequest->GetPresentationId(sessionId); if (NS_WARN_IF(NS_FAILED(rv))) { ctrlChannel->Disconnect(rv); return rv; } nsCOMPtr<nsIPresentationDevice> device; rv = aRequest->GetDevice(getter_AddRefs(device)); if (NS_WARN_IF(NS_FAILED(rv))) { ctrlChannel->Disconnect(rv); return rv; } // Create or reuse session info. RefPtr<PresentationSessionInfo> info = GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER); // This is the case for reconnecting a session. // Update the control channel and device of the session info. // Call |NotifyResponderReady| to indicate the receiver page is already there. if (info) { PRES_DEBUG("handle reconnection:id[%s]\n", NS_ConvertUTF16toUTF8(sessionId).get()); info->SetControlChannel(ctrlChannel); info->SetDevice(device); return static_cast<PresentationPresentingInfo*>(info.get())->DoReconnect(); } // This is the case for a new session. PRES_DEBUG("handle new session:url[%s], id[%s]\n", NS_ConvertUTF16toUTF8(url).get(), NS_ConvertUTF16toUTF8(sessionId).get()); info = new PresentationPresentingInfo(url, sessionId, device); rv = info->Init(ctrlChannel); if (NS_WARN_IF(NS_FAILED(rv))) { ctrlChannel->Disconnect(rv); return rv; } mSessionInfoAtReceiver.Put(sessionId, info); // Notify the receiver to launch. nsCOMPtr<nsIPresentationRequestUIGlue> glue = do_CreateInstance(PRESENTATION_REQUEST_UI_GLUE_CONTRACTID); if (NS_WARN_IF(!glue)) { ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR); return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR); } RefPtr<Promise> promise; rv = glue->SendRequest(url, sessionId, device, getter_AddRefs(promise)); if (NS_WARN_IF(NS_FAILED(rv))) { ctrlChannel->Disconnect(rv); return info->ReplyError(NS_ERROR_DOM_OPERATION_ERR); } static_cast<PresentationPresentingInfo*>(info.get())->SetPromise(promise); return NS_OK; }
/** * Performs initialization of the MANDATORY components of the Video Engine */ MediaConduitErrorCode WebrtcVideoConduit::Init(WebrtcVideoConduit *other) { CSFLogDebug(logTag, "%s this=%p other=%p", __FUNCTION__, this, other); #ifdef MOZILLA_INTERNAL_API // already know we must be on MainThread barring unit test weirdness MOZ_ASSERT(NS_IsMainThread()); nsresult rv; nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv); if (!NS_WARN_IF(NS_FAILED(rv))) { nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs); if (branch) { int32_t temp; NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.video.test_latency", &mVideoLatencyTestEnable))); NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.min_bitrate", &temp))); if (temp >= 0) { mMinBitrate = temp; } NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.start_bitrate", &temp))); if (temp >= 0) { mStartBitrate = temp; } NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.max_bitrate", &temp))); if (temp >= 0) { mMaxBitrate = temp; } } } #endif if (other) { MOZ_ASSERT(!other->mOtherDirection); other->mOtherDirection = this; mOtherDirection = other; // only one can call ::Create()/GetVideoEngine() MOZ_ASSERT(other->mVideoEngine); mVideoEngine = other->mVideoEngine; } else { #ifdef MOZ_WIDGET_ANDROID // get the JVM JavaVM *jvm = jsjni_GetVM(); if (webrtc::VideoEngine::SetAndroidObjects(jvm) != 0) { CSFLogError(logTag, "%s: could not set Android objects", __FUNCTION__); return kMediaConduitSessionNotInited; } #endif // Per WebRTC APIs below function calls return nullptr on failure if( !(mVideoEngine = webrtc::VideoEngine::Create()) ) { CSFLogError(logTag, "%s Unable to create video engine ", __FUNCTION__); return kMediaConduitSessionNotInited; } PRLogModuleInfo *logs = GetWebRTCLogInfo(); if (!gWebrtcTraceLoggingOn && logs && logs->level > 0) { // no need to a critical section or lock here gWebrtcTraceLoggingOn = 1; const char *file = PR_GetEnv("WEBRTC_TRACE_FILE"); if (!file) { file = "WebRTC.log"; } CSFLogDebug(logTag, "%s Logging webrtc to %s level %d", __FUNCTION__, file, logs->level); mVideoEngine->SetTraceFilter(logs->level); mVideoEngine->SetTraceFile(file); } } if( !(mPtrViEBase = ViEBase::GetInterface(mVideoEngine))) { CSFLogError(logTag, "%s Unable to get video base interface ", __FUNCTION__); return kMediaConduitSessionNotInited; } if( !(mPtrViECapture = ViECapture::GetInterface(mVideoEngine))) { CSFLogError(logTag, "%s Unable to get video capture interface", __FUNCTION__); return kMediaConduitSessionNotInited; } if( !(mPtrViECodec = ViECodec::GetInterface(mVideoEngine))) { CSFLogError(logTag, "%s Unable to get video codec interface ", __FUNCTION__); return kMediaConduitSessionNotInited; } if( !(mPtrViENetwork = ViENetwork::GetInterface(mVideoEngine))) { CSFLogError(logTag, "%s Unable to get video network interface ", __FUNCTION__); return kMediaConduitSessionNotInited; } if( !(mPtrViERender = ViERender::GetInterface(mVideoEngine))) { CSFLogError(logTag, "%s Unable to get video render interface ", __FUNCTION__); return kMediaConduitSessionNotInited; } if( !(mPtrRTP = webrtc::ViERTP_RTCP::GetInterface(mVideoEngine))) { CSFLogError(logTag, "%s Unable to get video RTCP interface ", __FUNCTION__); return kMediaConduitSessionNotInited; } if ( !(mPtrExtCodec = webrtc::ViEExternalCodec::GetInterface(mVideoEngine))) { CSFLogError(logTag, "%s Unable to get external codec interface %d ", __FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitSessionNotInited; } if (other) { mChannel = other->mChannel; mPtrExtCapture = other->mPtrExtCapture; mCapId = other->mCapId; } else { CSFLogDebug(logTag, "%s Engine Created: Init'ng the interfaces ",__FUNCTION__); if(mPtrViEBase->Init() == -1) { CSFLogError(logTag, " %s Video Engine Init Failed %d ",__FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitSessionNotInited; } if(mPtrViEBase->CreateChannel(mChannel) == -1) { CSFLogError(logTag, " %s Channel creation Failed %d ",__FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitChannelError; } if(mPtrViENetwork->RegisterSendTransport(mChannel, *this) == -1) { CSFLogError(logTag, "%s ViENetwork Failed %d ", __FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitTransportRegistrationFail; } if(mPtrViECapture->AllocateExternalCaptureDevice(mCapId, mPtrExtCapture) == -1) { CSFLogError(logTag, "%s Unable to Allocate capture module: %d ", __FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitCaptureError; } if(mPtrViECapture->ConnectCaptureDevice(mCapId,mChannel) == -1) { CSFLogError(logTag, "%s Unable to Connect capture module: %d ", __FUNCTION__,mPtrViEBase->LastError()); return kMediaConduitCaptureError; } if(mPtrViERender->AddRenderer(mChannel, webrtc::kVideoI420, (webrtc::ExternalRenderer*) this) == -1) { CSFLogError(logTag, "%s Failed to added external renderer ", __FUNCTION__); return kMediaConduitInvalidRenderer; } // Set up some parameters, per juberti. Set MTU. if(mPtrViENetwork->SetMTU(mChannel, 1200) != 0) { CSFLogError(logTag, "%s MTU Failed %d ", __FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitMTUError; } // Turn on RTCP and loss feedback reporting. if(mPtrRTP->SetRTCPStatus(mChannel, webrtc::kRtcpCompound_RFC4585) != 0) { CSFLogError(logTag, "%s RTCPStatus Failed %d ", __FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitRTCPStatusError; } } CSFLogError(logTag, "%s Initialization Done", __FUNCTION__); return kMediaConduitNoError; }
nsresult CreateFileTask::Work() { class AutoClose { public: explicit AutoClose(nsIOutputStream* aStream) : mStream(aStream) { MOZ_ASSERT(aStream); } ~AutoClose() { mStream->Close(); } private: nsCOMPtr<nsIOutputStream> mStream; }; MOZ_ASSERT(FileSystemUtils::IsParentProcess(), "Only call from parent process!"); MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!"); if (mFileSystem->IsShutdown()) { return NS_ERROR_FAILURE; } nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath); if (!file) { return NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR; } if (!mFileSystem->IsSafeFile(file)) { return NS_ERROR_DOM_SECURITY_ERR; } bool exists = false; nsresult rv = file->Exists(&exists); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (exists) { bool isFile = false; rv = file->IsFile(&isFile); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (!isFile) { return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR; } if (!mReplace) { return NS_ERROR_DOM_FILESYSTEM_PATH_EXISTS_ERR; } // Remove the old file before creating. rv = file->Remove(false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } rv = file->Create(nsIFile::NORMAL_FILE_TYPE, 0600); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } nsCOMPtr<nsIOutputStream> outputStream; rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), file); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } AutoClose acOutputStream(outputStream); nsCOMPtr<nsIOutputStream> bufferedOutputStream; rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), outputStream, sOutputBufferSize); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } AutoClose acBufferedOutputStream(bufferedOutputStream); if (mBlobStream) { // Write the file content from blob data. uint64_t bufSize = 0; rv = mBlobStream->Available(&bufSize); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } while (bufSize && !mFileSystem->IsShutdown()) { uint32_t written = 0; uint32_t writeSize = bufSize < UINT32_MAX ? bufSize : UINT32_MAX; rv = bufferedOutputStream->WriteFrom(mBlobStream, writeSize, &written); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } bufSize -= written; } mBlobStream->Close(); mBlobStream = nullptr; if (mFileSystem->IsShutdown()) { return NS_ERROR_FAILURE; } mTargetBlobImpl = new BlobImplFile(file); return NS_OK; } // Write file content from array data. uint32_t written; rv = bufferedOutputStream->Write( reinterpret_cast<char*>(mArrayData.Elements()), mArrayData.Length(), &written); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (mArrayData.Length() != written) { return NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR; } mTargetBlobImpl = new BlobImplFile(file); return NS_OK; }
nsresult UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort, const bool& aAddressReuse, const bool& aLoopback, const uint32_t& recvBufferSize, const uint32_t& sendBufferSize) { nsresult rv; UDPSOCKET_LOG(("%s: [this=%p] %s:%u addressReuse: %d loopback: %d recvBufferSize: %" PRIu32 ", sendBufferSize: %" PRIu32, __FUNCTION__, this, nsCString(aHost).get(), aPort, aAddressReuse, aLoopback, recvBufferSize, sendBufferSize)); nsCOMPtr<nsIUDPSocket> sock = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (aHost.IsEmpty()) { rv = sock->Init(aPort, false, mPrincipal, aAddressReuse, /* optional_argc = */ 1); } else { PRNetAddr prAddr; PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr); PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr); if (status != PR_SUCCESS) { return NS_ERROR_FAILURE; } mozilla::net::NetAddr addr; PRNetAddrToNetAddr(&prAddr, &addr); rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse, /* optional_argc = */ 1); } if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } nsCOMPtr<nsINetAddr> laddr; rv = sock->GetLocalAddr(getter_AddRefs(laddr)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } uint16_t family; rv = laddr->GetFamily(&family); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (family == nsINetAddr::FAMILY_INET) { rv = sock->SetMulticastLoopback(aLoopback); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } // TODO: once bug 1252759 is fixed query buffer first and only increase if (recvBufferSize != 0) { rv = sock->SetRecvBufferSize(recvBufferSize); if (NS_WARN_IF(NS_FAILED(rv))) { UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set recv buffer size to: %" PRIu32, __FUNCTION__, this, nsCString(aHost).get(), aPort, recvBufferSize)); } } if (sendBufferSize != 0) { rv = sock->SetSendBufferSize(sendBufferSize); if (NS_WARN_IF(NS_FAILED(rv))) { UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set send buffer size to: %" PRIu32, __FUNCTION__, this, nsCString(aHost).get(), aPort, sendBufferSize)); } } // register listener rv = sock->AsyncListen(this); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } mSocket = sock; return NS_OK; }
nsresult EventListenerManager::CompileEventHandlerInternal(Listener* aListener, const nsAString* aBody, Element* aElement) { MOZ_ASSERT(aListener->GetJSEventHandler()); MOZ_ASSERT(aListener->mHandlerIsString, "Why are we compiling a non-string JS listener?"); JSEventHandler* jsEventHandler = aListener->GetJSEventHandler(); MOZ_ASSERT(!jsEventHandler->GetTypedEventHandler().HasEventHandler(), "What is there to compile?"); nsresult result = NS_OK; nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIScriptGlobalObject> global = GetScriptGlobalAndDocument(getter_AddRefs(doc)); NS_ENSURE_STATE(global); // Activate JSAPI, and make sure that exceptions are reported on the right // Window. AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(global))) { return NS_ERROR_UNEXPECTED; } jsapi.TakeOwnershipOfErrorReporting(); JSContext* cx = jsapi.cx(); nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom; nsIAtom* attrName = typeAtom; // Flag us as not a string so we don't keep trying to compile strings which // can't be compiled. aListener->mHandlerIsString = false; // mTarget may not be an Element if it's a window and we're // getting an inline event listener forwarded from <html:body> or // <html:frameset> or <xul:window> or the like. // XXX I don't like that we have to reference content from // here. The alternative is to store the event handler string on // the JSEventHandler itself, and that still doesn't address // the arg names issue. nsCOMPtr<Element> element = do_QueryInterface(mTarget); MOZ_ASSERT(element || aBody, "Where will we get our body?"); nsAutoString handlerBody; const nsAString* body = aBody; if (!aBody) { if (aListener->mTypeAtom == nsGkAtoms::onSVGLoad) { attrName = nsGkAtoms::onload; } else if (aListener->mTypeAtom == nsGkAtoms::onSVGUnload) { attrName = nsGkAtoms::onunload; } else if (aListener->mTypeAtom == nsGkAtoms::onSVGResize) { attrName = nsGkAtoms::onresize; } else if (aListener->mTypeAtom == nsGkAtoms::onSVGScroll) { attrName = nsGkAtoms::onscroll; } else if (aListener->mTypeAtom == nsGkAtoms::onSVGZoom) { attrName = nsGkAtoms::onzoom; } else if (aListener->mTypeAtom == nsGkAtoms::onbeginEvent) { attrName = nsGkAtoms::onbegin; } else if (aListener->mTypeAtom == nsGkAtoms::onrepeatEvent) { attrName = nsGkAtoms::onrepeat; } else if (aListener->mTypeAtom == nsGkAtoms::onendEvent) { attrName = nsGkAtoms::onend; } element->GetAttr(kNameSpaceID_None, attrName, handlerBody); body = &handlerBody; aElement = element; } aListener = nullptr; uint32_t lineNo = 0; nsAutoCString url (NS_LITERAL_CSTRING("-moz-evil:lying-event-listener")); MOZ_ASSERT(body); MOZ_ASSERT(aElement); nsIURI *uri = aElement->OwnerDoc()->GetDocumentURI(); if (uri) { uri->GetSpec(url); lineNo = 1; } nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget); uint32_t argCount; const char **argNames; nsContentUtils::GetEventArgNames(aElement->GetNameSpaceID(), typeAtom, win, &argCount, &argNames); JSAddonId *addonId = MapURIToAddonID(uri); // Wrap the event target, so that we can use it as the scope for the event // handler. Note that mTarget is different from aElement in the <body> case, // where mTarget is a Window. // // The wrapScope doesn't really matter here, because the target will create // its reflector in the proper scope, and then we'll enter that compartment. JS::Rooted<JSObject*> wrapScope(cx, global->GetGlobalJSObject()); JS::Rooted<JS::Value> v(cx); { JSAutoCompartment ac(cx, wrapScope); nsresult rv = nsContentUtils::WrapNative(cx, mTarget, &v, /* aAllowWrapping = */ false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } if (addonId) { JS::Rooted<JSObject*> vObj(cx, &v.toObject()); JS::Rooted<JSObject*> addonScope(cx, xpc::GetAddonScope(cx, vObj, addonId)); if (!addonScope) { return NS_ERROR_FAILURE; } JSAutoCompartment ac(cx, addonScope); // Wrap our event target into the addon scope, since that's where we want to // do all our work. if (!JS_WrapValue(cx, &v)) { return NS_ERROR_FAILURE; } } JS::Rooted<JSObject*> target(cx, &v.toObject()); JSAutoCompartment ac(cx, target); // Now that we've entered the compartment we actually care about, create our // scope chain. Note that we start with |element|, not aElement, because // mTarget is different from aElement in the <body> case, where mTarget is a // Window, and in that case we do not want the scope chain to include the body // or the document. JS::AutoObjectVector scopeChain(cx); if (!nsJSUtils::GetScopeChainForElement(cx, element, scopeChain)) { return NS_ERROR_OUT_OF_MEMORY; } nsDependentAtomString str(attrName); // Most of our names are short enough that we don't even have to malloc // the JS string stuff, so don't worry about playing games with // refcounting XPCOM stringbuffers. JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx, str.BeginReading(), str.Length())); NS_ENSURE_TRUE(jsStr, NS_ERROR_OUT_OF_MEMORY); // Get the reflector for |aElement|, so that we can pass to setElement. if (NS_WARN_IF(!GetOrCreateDOMReflector(cx, target, aElement, &v))) { return NS_ERROR_FAILURE; } JS::CompileOptions options(cx); options.setIntroductionType("eventHandler") .setFileAndLine(url.get(), lineNo) .setVersion(JSVERSION_DEFAULT) .setElement(&v.toObject()) .setElementAttributeName(jsStr); JS::Rooted<JSObject*> handler(cx); result = nsJSUtils::CompileFunction(jsapi, scopeChain, options, nsAtomCString(typeAtom), argCount, argNames, *body, handler.address()); NS_ENSURE_SUCCESS(result, result); NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE); if (jsEventHandler->EventName() == nsGkAtoms::onerror && win) { nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback = new OnErrorEventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr); jsEventHandler->SetHandler(handlerCallback); } else if (jsEventHandler->EventName() == nsGkAtoms::onbeforeunload && win) { nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback = new OnBeforeUnloadEventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr); jsEventHandler->SetHandler(handlerCallback); } else { nsRefPtr<EventHandlerNonNull> handlerCallback = new EventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr); jsEventHandler->SetHandler(handlerCallback); } return result; }
nsresult UDPSocket::Init(const nsString& aLocalAddress, const Nullable<uint16_t>& aLocalPort, const bool& aAddressReuse, const bool& aLoopback) { MOZ_ASSERT(!mSocket && !mSocketChild); mLocalAddress = aLocalAddress; mLocalPort = aLocalPort; mAddressReuse = aAddressReuse; mLoopback = aLoopback; ErrorResult rv; nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner()); mOpened = Promise::Create(global, rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } mClosed = Promise::Create(global, rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } class OpenSocketRunnable final : public nsRunnable { public: explicit OpenSocketRunnable(UDPSocket* aSocket) : mSocket(aSocket) { } NS_IMETHOD Run() override { MOZ_ASSERT(mSocket); if (mSocket->mReadyState != SocketReadyState::Opening) { return NS_OK; } uint16_t localPort = 0; if (!mSocket->mLocalPort.IsNull()) { localPort = mSocket->mLocalPort.Value(); } nsresult rv; if (XRE_GetProcessType() != GeckoProcessType_Default) { rv = mSocket->InitRemote(mSocket->mLocalAddress, localPort); } else { rv = mSocket->InitLocal(mSocket->mLocalAddress, localPort); } if (NS_WARN_IF(NS_FAILED(rv))) { mSocket->CloseWithReason(NS_ERROR_DOM_NETWORK_ERR); } return NS_OK; } private: nsRefPtr<UDPSocket> mSocket; }; nsCOMPtr<nsIRunnable> runnable = new OpenSocketRunnable(this); return NS_DispatchToMainThread(runnable); }
bool UDPSocket::Send(const StringOrBlobOrArrayBufferOrArrayBufferView& aData, const Optional<nsAString>& aRemoteAddress, const Optional<Nullable<uint16_t>>& aRemotePort, ErrorResult& aRv) { if (mReadyState != SocketReadyState::Open) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return false; } MOZ_ASSERT(mSocket || mSocketChild); // If the remote address and port were not specified in the constructor or as arguments, // throw InvalidAccessError. nsCString remoteAddress; if (aRemoteAddress.WasPassed()) { remoteAddress = NS_ConvertUTF16toUTF8(aRemoteAddress.Value()); UDPSOCKET_LOG(("%s: Send to %s", __FUNCTION__, remoteAddress.get())); } else if (!mRemoteAddress.IsVoid()) { remoteAddress = mRemoteAddress; UDPSOCKET_LOG(("%s: Send to %s", __FUNCTION__, remoteAddress.get())); } else { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return false; } uint16_t remotePort; if (aRemotePort.WasPassed() && !aRemotePort.Value().IsNull()) { remotePort = aRemotePort.Value().Value(); } else if (!mRemotePort.IsNull()) { remotePort = mRemotePort.Value(); } else { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return false; } nsCOMPtr<nsIInputStream> stream; if (aData.IsBlob()) { Blob& blob = aData.GetAsBlob(); blob.GetInternalStream(getter_AddRefs(stream), aRv); if (NS_WARN_IF(aRv.Failed())) { return false; } } else { nsresult rv; nsCOMPtr<nsIStringInputStream> strStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv); if (NS_WARN_IF(NS_FAILED(rv))) { aRv.Throw(rv); return false; } if (aData.IsString()) { NS_ConvertUTF16toUTF8 data(aData.GetAsString()); aRv = strStream->SetData(data.BeginReading(), data.Length()); } else if (aData.IsArrayBuffer()) { const ArrayBuffer& data = aData.GetAsArrayBuffer(); data.ComputeLengthAndData(); aRv = strStream->SetData(reinterpret_cast<const char*>(data.Data()), data.Length()); } else { const ArrayBufferView& data = aData.GetAsArrayBufferView(); data.ComputeLengthAndData(); aRv = strStream->SetData(reinterpret_cast<const char*>(data.Data()), data.Length()); } if (NS_WARN_IF(aRv.Failed())) { return false; } stream = strStream; } if (mSocket) { aRv = mSocket->SendBinaryStream(remoteAddress, remotePort, stream); } else if (mSocketChild) { aRv = mSocketChild->SendBinaryStream(remoteAddress, remotePort, stream); } if (NS_WARN_IF(aRv.Failed())) { return false; } return true; }
NS_IMETHODIMP PresentationService::StartSession( const nsTArray<nsString>& aUrls, const nsAString& aSessionId, const nsAString& aOrigin, const nsAString& aDeviceId, uint64_t aWindowId, nsIDOMEventTarget* aEventTarget, nsIPrincipal* aPrincipal, nsIPresentationServiceCallback* aCallback, nsIPresentationTransportBuilderConstructor* aBuilderConstructor) { PRES_DEBUG("%s:id[%s]\n", __func__, NS_ConvertUTF16toUTF8(aSessionId).get()); MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aCallback); MOZ_ASSERT(!aSessionId.IsEmpty()); MOZ_ASSERT(!aUrls.IsEmpty()); nsCOMPtr<nsIPresentationDeviceRequest> request = new PresentationDeviceRequest(aUrls, aSessionId, aOrigin, aWindowId, aEventTarget, aPrincipal, aCallback, aBuilderConstructor); if (aDeviceId.IsVoid()) { // Pop up a prompt and ask user to select a device. nsCOMPtr<nsIPresentationDevicePrompt> prompt = do_GetService(PRESENTATION_DEVICE_PROMPT_CONTRACTID); if (NS_WARN_IF(!prompt)) { return aCallback->NotifyError(NS_ERROR_DOM_INVALID_ACCESS_ERR); } nsresult rv = prompt->PromptDeviceSelection(request); if (NS_WARN_IF(NS_FAILED(rv))) { return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); } return NS_OK; } // Find the designated device from available device list. nsCOMPtr<nsIPresentationDeviceManager> deviceManager = do_GetService(PRESENTATION_DEVICE_MANAGER_CONTRACTID); if (NS_WARN_IF(!deviceManager)) { return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); } nsCOMPtr<nsIArray> presentationUrls; if (NS_WARN_IF(NS_FAILED( ConvertURLArrayHelper(aUrls, getter_AddRefs(presentationUrls))))) { return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); } nsCOMPtr<nsIArray> devices; nsresult rv = deviceManager->GetAvailableDevices(presentationUrls, getter_AddRefs(devices)); if (NS_WARN_IF(NS_FAILED(rv))) { return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); } nsCOMPtr<nsISimpleEnumerator> enumerator; rv = devices->Enumerate(getter_AddRefs(enumerator)); if (NS_WARN_IF(NS_FAILED(rv))) { return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR); } NS_ConvertUTF16toUTF8 utf8DeviceId(aDeviceId); bool hasMore; while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) { nsCOMPtr<nsISupports> isupports; rv = enumerator->GetNext(getter_AddRefs(isupports)); nsCOMPtr<nsIPresentationDevice> device(do_QueryInterface(isupports)); MOZ_ASSERT(device); nsAutoCString id; if (NS_SUCCEEDED(device->GetId(id)) && id.Equals(utf8DeviceId)) { request->Select(device); return NS_OK; } } // Reject if designated device is not available. return aCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR); }