1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/protocol/rtsp/RtspChannelChild.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,271 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set sw=2 ts=8 et tw=80 : */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "RtspChannelChild.h" 1.11 +#include "mozilla/ipc/URIUtils.h" 1.12 + 1.13 +using namespace mozilla::ipc; 1.14 + 1.15 +namespace mozilla { 1.16 +namespace net { 1.17 + 1.18 +//----------------------------------------------------------------------------- 1.19 +// RtspChannelChild 1.20 +//----------------------------------------------------------------------------- 1.21 +RtspChannelChild::RtspChannelChild(nsIURI *aUri) 1.22 + : mIPCOpen(false) 1.23 + , mCanceled(false) 1.24 +{ 1.25 + nsBaseChannel::SetURI(aUri); 1.26 +} 1.27 + 1.28 +RtspChannelChild::~RtspChannelChild() 1.29 +{ 1.30 +} 1.31 + 1.32 +nsIStreamingProtocolController* 1.33 +RtspChannelChild::GetController() 1.34 +{ 1.35 + return mMediaStreamController; 1.36 +} 1.37 + 1.38 +void 1.39 +RtspChannelChild::ReleaseController() 1.40 +{ 1.41 + if (mMediaStreamController) { 1.42 + mMediaStreamController = nullptr; 1.43 + } 1.44 +} 1.45 + 1.46 +//----------------------------------------------------------------------------- 1.47 +// IPDL 1.48 +//----------------------------------------------------------------------------- 1.49 +void 1.50 +RtspChannelChild::AddIPDLReference() 1.51 +{ 1.52 + NS_ABORT_IF_FALSE(!mIPCOpen, 1.53 + "Attempt to retain more than one IPDL reference"); 1.54 + mIPCOpen = true; 1.55 + AddRef(); 1.56 +} 1.57 + 1.58 +void 1.59 +RtspChannelChild::ReleaseIPDLReference() 1.60 +{ 1.61 + NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference"); 1.62 + mIPCOpen = false; 1.63 + Release(); 1.64 +} 1.65 + 1.66 +//----------------------------------------------------------------------------- 1.67 +// nsISupports 1.68 +//----------------------------------------------------------------------------- 1.69 +NS_IMPL_ISUPPORTS_INHERITED(RtspChannelChild, 1.70 + nsBaseChannel, 1.71 + nsIChannel, 1.72 + nsIChildChannel) 1.73 + 1.74 +//----------------------------------------------------------------------------- 1.75 +// nsBaseChannel::nsIChannel 1.76 +//----------------------------------------------------------------------------- 1.77 +NS_IMETHODIMP 1.78 +RtspChannelChild::GetContentType(nsACString& aContentType) 1.79 +{ 1.80 + aContentType.AssignLiteral("RTSP"); 1.81 + return NS_OK; 1.82 +} 1.83 + 1.84 +class CallListenerOnStartRequestEvent : public nsRunnable 1.85 +{ 1.86 +public: 1.87 + CallListenerOnStartRequestEvent(nsIStreamListener *aListener, 1.88 + nsIRequest *aRequest, nsISupports *aContext) 1.89 + : mListener(aListener) 1.90 + , mRequest(aRequest) 1.91 + , mContext(aContext) 1.92 + { 1.93 + MOZ_RELEASE_ASSERT(aListener); 1.94 + } 1.95 + NS_IMETHOD Run() 1.96 + { 1.97 + MOZ_ASSERT(NS_IsMainThread()); 1.98 + mListener->OnStartRequest(mRequest, mContext); 1.99 + return NS_OK; 1.100 + } 1.101 +private: 1.102 + nsRefPtr<nsIStreamListener> mListener; 1.103 + nsRefPtr<nsIRequest> mRequest; 1.104 + nsRefPtr<nsISupports> mContext; 1.105 +}; 1.106 + 1.107 +NS_IMETHODIMP 1.108 +RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext) 1.109 +{ 1.110 + // Precondition checks. 1.111 + MOZ_ASSERT(aListener); 1.112 + nsCOMPtr<nsIURI> uri = nsBaseChannel::URI(); 1.113 + NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE); 1.114 + 1.115 + // Create RtspController. 1.116 + nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService = 1.117 + do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID); 1.118 + MOZ_RELEASE_ASSERT(mediaControllerService, 1.119 + "Cannot proceed if media controller service is unavailable!"); 1.120 + mediaControllerService->Create(this, getter_AddRefs(mMediaStreamController)); 1.121 + MOZ_ASSERT(mMediaStreamController); 1.122 + 1.123 + // Add ourselves to the load group. 1.124 + if (mLoadGroup) { 1.125 + mLoadGroup->AddRequest(this, nullptr); 1.126 + } 1.127 + 1.128 + // Dispatch mListener's OnStartRequest directly. mListener is expected to 1.129 + // create an RtspMediaResource and use the RtspController we just created to 1.130 + // manage the control and data streams to and from the network. 1.131 + mListener = aListener; 1.132 + mListenerContext = aContext; 1.133 + NS_DispatchToMainThread( 1.134 + new CallListenerOnStartRequestEvent(mListener, this, mListenerContext)); 1.135 + 1.136 + return NS_OK; 1.137 +} 1.138 + 1.139 +//----------------------------------------------------------------------------- 1.140 +// nsBaseChannel::nsIStreamListener::nsIRequestObserver 1.141 +//----------------------------------------------------------------------------- 1.142 +NS_IMETHODIMP 1.143 +RtspChannelChild::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) 1.144 +{ 1.145 + MOZ_CRASH("Should never be called"); 1.146 +} 1.147 + 1.148 +NS_IMETHODIMP 1.149 +RtspChannelChild::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext, 1.150 + nsresult aStatusCode) 1.151 +{ 1.152 + MOZ_CRASH("Should never be called"); 1.153 +} 1.154 + 1.155 +//----------------------------------------------------------------------------- 1.156 +// nsBaseChannel::nsIStreamListener 1.157 +//----------------------------------------------------------------------------- 1.158 +NS_IMETHODIMP 1.159 +RtspChannelChild::OnDataAvailable(nsIRequest *aRequest, 1.160 + nsISupports *aContext, 1.161 + nsIInputStream *aInputStream, 1.162 + uint64_t aOffset, 1.163 + uint32_t aCount) 1.164 +{ 1.165 + MOZ_CRASH("Should never be called"); 1.166 +} 1.167 + 1.168 +//----------------------------------------------------------------------------- 1.169 +// nsBaseChannel::nsIChannel::nsIRequest 1.170 +//----------------------------------------------------------------------------- 1.171 +class CallListenerOnStopRequestEvent : public nsRunnable 1.172 +{ 1.173 +public: 1.174 + CallListenerOnStopRequestEvent(nsIStreamListener *aListener, 1.175 + nsIRequest *aRequest, 1.176 + nsISupports *aContext, nsresult aStatus) 1.177 + : mListener(aListener) 1.178 + , mRequest(aRequest) 1.179 + , mContext(aContext) 1.180 + , mStatus(aStatus) 1.181 + { 1.182 + MOZ_RELEASE_ASSERT(aListener); 1.183 + } 1.184 + NS_IMETHOD Run() 1.185 + { 1.186 + MOZ_ASSERT(NS_IsMainThread()); 1.187 + mListener->OnStopRequest(mRequest, mContext, mStatus); 1.188 + return NS_OK; 1.189 + } 1.190 +private: 1.191 + nsRefPtr<nsIStreamListener> mListener; 1.192 + nsRefPtr<nsIRequest> mRequest; 1.193 + nsRefPtr<nsISupports> mContext; 1.194 + nsresult mStatus; 1.195 +}; 1.196 + 1.197 +NS_IMETHODIMP 1.198 +RtspChannelChild::Cancel(nsresult status) 1.199 +{ 1.200 + if (mCanceled) { 1.201 + return NS_OK; 1.202 + } 1.203 + 1.204 + mCanceled = true; 1.205 + // Stop RtspController. 1.206 + if (mMediaStreamController) { 1.207 + mMediaStreamController->Stop(); 1.208 + } 1.209 + 1.210 + // Call mListener's OnStopRequest to do clean up. 1.211 + NS_DispatchToMainThread( 1.212 + new CallListenerOnStopRequestEvent(mListener, this, 1.213 + mListenerContext, status)); 1.214 + mListener = nullptr; 1.215 + mListenerContext = nullptr; 1.216 + 1.217 + // Remove ourselves from the load group. 1.218 + if (mLoadGroup) { 1.219 + mLoadGroup->RemoveRequest(this, nullptr, status); 1.220 + } 1.221 + 1.222 + return NS_OK; 1.223 +} 1.224 + 1.225 +NS_IMETHODIMP 1.226 +RtspChannelChild::Suspend() 1.227 +{ 1.228 + MOZ_CRASH("Should never be called"); 1.229 +} 1.230 + 1.231 +NS_IMETHODIMP 1.232 +RtspChannelChild::Resume() 1.233 +{ 1.234 + MOZ_CRASH("Should never be called"); 1.235 +} 1.236 + 1.237 +//----------------------------------------------------------------------------- 1.238 +// nsBaseChannel 1.239 +//----------------------------------------------------------------------------- 1.240 +NS_IMETHODIMP 1.241 +RtspChannelChild::OpenContentStream(bool aAsync, 1.242 + nsIInputStream **aStream, 1.243 + nsIChannel **aChannel) 1.244 +{ 1.245 + MOZ_CRASH("Should never be called"); 1.246 +} 1.247 + 1.248 +//----------------------------------------------------------------------------- 1.249 +// nsIChildChannel 1.250 +//----------------------------------------------------------------------------- 1.251 +NS_IMETHODIMP 1.252 +RtspChannelChild::ConnectParent(uint32_t id) 1.253 +{ 1.254 + // Create RtspChannelParent for redirection. 1.255 + AddIPDLReference(); 1.256 + RtspChannelConnectArgs connectArgs; 1.257 + SerializeURI(nsBaseChannel::URI(), connectArgs.uri()); 1.258 + connectArgs.channelId() = id; 1.259 + if (!gNeckoChild->SendPRtspChannelConstructor(this, connectArgs)) { 1.260 + return NS_ERROR_FAILURE; 1.261 + } 1.262 + 1.263 + return NS_OK; 1.264 +} 1.265 + 1.266 +NS_IMETHODIMP 1.267 +RtspChannelChild::CompleteRedirectSetup(nsIStreamListener *aListener, 1.268 + nsISupports *aContext) 1.269 +{ 1.270 + return AsyncOpen(aListener, aContext); 1.271 +} 1.272 + 1.273 +} // namespace net 1.274 +} // namespace mozilla