netwerk/protocol/rtsp/controller/RtspControllerChild.cpp

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set sw=2 ts=8 et tw=80 : */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "RtspControllerChild.h"
     8 #include "RtspMetaData.h"
     9 #include "mozilla/dom/TabChild.h"
    10 #include "mozilla/net/NeckoChild.h"
    11 #include "nsITabChild.h"
    12 #include "nsILoadContext.h"
    13 #include "nsNetUtil.h"
    14 #include "mozilla/ipc/InputStreamUtils.h"
    15 #include "mozilla/ipc/URIUtils.h"
    16 #include "nsStringStream.h"
    17 #include "prlog.h"
    19 PRLogModuleInfo* gRtspChildLog = nullptr;
    20 #undef LOG
    21 #define LOG(args) PR_LOG(gRtspChildLog, PR_LOG_DEBUG, args)
    23 const uint32_t kRtspTotalTracks = 2;
    24 using namespace mozilla::ipc;
    26 namespace mozilla {
    27 namespace net {
    29 NS_IMPL_ADDREF(RtspControllerChild)
    31 NS_IMETHODIMP_(nsrefcnt) RtspControllerChild::Release()
    32 {
    33   NS_PRECONDITION(0 != mRefCnt, "dup release");
    34   // Enable this to find non-threadsafe destructors:
    35   // NS_ASSERT_OWNINGTHREAD(RtspControllerChild);
    36   --mRefCnt;
    37   NS_LOG_RELEASE(this, mRefCnt, "RtspControllerChild");
    39   if (mRefCnt == 1 && mIPCOpen) {
    40     Send__delete__(this);
    41     return mRefCnt;
    42   }
    44   if (mRefCnt == 0) {
    45     mRefCnt = 1; /* stabilize */
    46     delete this;
    47     return 0;
    48   }
    49   return mRefCnt;
    50 }
    52 NS_INTERFACE_MAP_BEGIN(RtspControllerChild)
    53   NS_INTERFACE_MAP_ENTRY(nsIStreamingProtocolController)
    54   NS_INTERFACE_MAP_ENTRY(nsIStreamingProtocolListener)
    55   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamingProtocolController)
    56 NS_INTERFACE_MAP_END
    58 //-----------------------------------------------------------------------------
    59 // RtspControllerChild methods
    60 //-----------------------------------------------------------------------------
    61 RtspControllerChild::RtspControllerChild(nsIChannel *channel)
    62   : mIPCOpen(false)
    63   , mIPCAllowed(false)
    64   , mChannel(channel)
    65   , mTotalTracks(0)
    66   , mSuspendCount(0)
    67 {
    68 #if defined(PR_LOGGING)
    69   if (!gRtspChildLog)
    70     gRtspChildLog = PR_NewLogModule("nsRtspChild");
    71 #endif
    72   AddIPDLReference();
    73   gNeckoChild->SendPRtspControllerConstructor(this);
    74 }
    76 RtspControllerChild::~RtspControllerChild()
    77 {
    78   LOG(("RtspControllerChild::~RtspControllerChild()"));
    79 }
    81 void
    82 RtspControllerChild::ReleaseChannel()
    83 {
    84   static_cast<RtspChannelChild*>(mChannel.get())->ReleaseController();
    85 }
    87 bool
    88 RtspControllerChild::OKToSendIPC()
    89 {
    90   MOZ_ASSERT(NS_IsMainThread());
    91   if (mIPCOpen == false) {
    92     return false;
    93   }
    94   return mIPCAllowed;
    95 }
    97 void
    98 RtspControllerChild::AllowIPC()
    99 {
   100   MOZ_ASSERT(NS_IsMainThread());
   101   mIPCAllowed = true;
   102 }
   104 void
   105 RtspControllerChild::DisallowIPC()
   106 {
   107   MOZ_ASSERT(NS_IsMainThread());
   108   mIPCAllowed = false;
   109 }
   111 //-----------------------------------------------------------------------------
   112 // RtspControllerChild::PRtspControllerChild
   113 //-----------------------------------------------------------------------------
   114 bool
   115 RtspControllerChild::RecvOnMediaDataAvailable(
   116                        const uint8_t& index,
   117                        const nsCString& data,
   118                        const uint32_t& length,
   119                        const uint32_t& offset,
   120                        const InfallibleTArray<RtspMetadataParam>& metaArray)
   121 {
   122   nsRefPtr<RtspMetaData> meta = new RtspMetaData();
   123   nsresult rv = meta->DeserializeRtspMetaData(metaArray);
   124   NS_ENSURE_SUCCESS(rv, true);
   126   if (mListener) {
   127     mListener->OnMediaDataAvailable(index, data, length, offset, meta.get());
   128   }
   129   return true;
   130 }
   132 void
   133 RtspControllerChild::AddMetaData(
   134                        already_AddRefed<nsIStreamingProtocolMetaData>&& meta)
   135 {
   136   nsCOMPtr<nsIStreamingProtocolMetaData> data = meta;
   137   mMetaArray.AppendElement(data);
   138 }
   140 int
   141 RtspControllerChild::GetMetaDataLength()
   142 {
   143   return mMetaArray.Length();
   144 }
   146 bool
   147 RtspControllerChild::RecvOnConnected(
   148                        const uint8_t& index,
   149                        const InfallibleTArray<RtspMetadataParam>& metaArray)
   150 {
   151   // Deserialize meta data.
   152   nsRefPtr<RtspMetaData> meta = new RtspMetaData();
   153   nsresult rv = meta->DeserializeRtspMetaData(metaArray);
   154   NS_ENSURE_SUCCESS(rv, true);
   155   meta->GetTotalTracks(&mTotalTracks);
   156   if (mTotalTracks <= 0) {
   157     LOG(("RtspControllerChild::RecvOnConnected invalid tracks %d", mTotalTracks));
   158     // Set the default value.
   159     mTotalTracks = kRtspTotalTracks;
   160   }
   161   AddMetaData(meta.forget().downcast<nsIStreamingProtocolMetaData>());
   163   // Notify the listener when meta data of tracks are available.
   164   if ((static_cast<uint32_t>(index) + 1) == mTotalTracks) {
   165     // The controller provide |GetTrackMetaData| method for his client.
   166     if (mListener) {
   167       mListener->OnConnected(index, nullptr);
   168     }
   169   }
   170   return true;
   171 }
   173 bool
   174 RtspControllerChild::RecvOnDisconnected(
   175                        const uint8_t& index,
   176                        const nsresult& reason)
   177 {
   178   DisallowIPC();
   179   LOG(("RtspControllerChild::RecvOnDisconnected for track %d reason = 0x%x", index, reason));
   180   if (mListener) {
   181     mListener->OnDisconnected(index, reason);
   182   }
   183   ReleaseChannel();
   184   return true;
   185 }
   187 bool
   188 RtspControllerChild::RecvAsyncOpenFailed(const nsresult& reason)
   189 {
   190   DisallowIPC();
   191   LOG(("RtspControllerChild::RecvAsyncOpenFailed reason = 0x%x", reason));
   192   if (mListener) {
   193     mListener->OnDisconnected(0, NS_ERROR_CONNECTION_REFUSED);
   194   }
   195   ReleaseChannel();
   196   return true;
   197 }
   199 void
   200 RtspControllerChild::AddIPDLReference()
   201 {
   202   NS_ABORT_IF_FALSE(!mIPCOpen,
   203                     "Attempt to retain more than one IPDL reference");
   204   mIPCOpen = true;
   205   AllowIPC();
   206   AddRef();
   207 }
   209 void
   210 RtspControllerChild::ReleaseIPDLReference()
   211 {
   212   NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
   213   mIPCOpen = false;
   214   DisallowIPC();
   215   Release();
   216 }
   218 NS_IMETHODIMP
   219 RtspControllerChild::GetTrackMetaData(
   220                        uint8_t index,
   221                        nsIStreamingProtocolMetaData **result)
   222 {
   223   if (GetMetaDataLength() <= 0 || index >= GetMetaDataLength()) {
   224     LOG(("RtspControllerChild:: meta data is not available"));
   225     return NS_ERROR_NOT_INITIALIZED;
   226   }
   227   LOG(("RtspControllerChild::GetTrackMetaData() %d", index));
   228   NS_IF_ADDREF(*result = mMetaArray[index]);
   229   return NS_OK;
   230 }
   232 enum IPCEvent
   233 {
   234   SendNoneEvent = 0,
   235   SendPlayEvent,
   236   SendPauseEvent,
   237   SendSeekEvent,
   238   SendResumeEvent,
   239   SendSuspendEvent,
   240   SendStopEvent
   241 };
   243 class SendIPCEvent : public nsRunnable
   244 {
   245 public:
   246   SendIPCEvent(RtspControllerChild *aController, IPCEvent aEvent)
   247     : mController(aController)
   248     , mEvent(aEvent)
   249     , mSeekTime(0)
   250   {
   251   }
   253   SendIPCEvent(RtspControllerChild *aController,
   254                IPCEvent aEvent,
   255                uint64_t aSeekTime)
   256     : mController(aController)
   257     , mEvent(aEvent)
   258     , mSeekTime(aSeekTime)
   259   {
   260   }
   262   NS_IMETHOD Run()
   263   {
   264     MOZ_ASSERT(NS_IsMainThread());
   265     if (mController->OKToSendIPC() == false) {
   266       // Don't send any more IPC events; no guarantee that parent objects are
   267       // still alive.
   268       return NS_ERROR_FAILURE;
   269     }
   270     bool rv = true;
   272     if (mEvent == SendPlayEvent) {
   273       rv = mController->SendPlay();
   274     } else if (mEvent == SendPauseEvent) {
   275       rv = mController->SendPause();
   276     } else if (mEvent == SendSeekEvent) {
   277       rv = mController->SendSeek(mSeekTime);
   278     } else if (mEvent == SendResumeEvent) {
   279       rv = mController->SendResume();
   280     } else if (mEvent == SendSuspendEvent) {
   281       rv = mController->SendSuspend();
   282     } else if (mEvent == SendStopEvent) {
   283       rv = mController->SendStop();
   284     } else {
   285       LOG(("RtspControllerChild::SendIPCEvent"));
   286     }
   287     if (!rv) {
   288       return NS_ERROR_FAILURE;
   289     }
   290     return NS_OK;
   291   }
   292 private:
   293   nsRefPtr<RtspControllerChild> mController;
   294   IPCEvent mEvent;
   295   uint64_t mSeekTime;
   296 };
   298 //-----------------------------------------------------------------------------
   299 // RtspControllerChild::nsIStreamingProtocolController
   300 //-----------------------------------------------------------------------------
   301 NS_IMETHODIMP
   302 RtspControllerChild::Play(void)
   303 {
   304   LOG(("RtspControllerChild::Play()"));
   306   if (NS_IsMainThread()) {
   307     if (!OKToSendIPC() || !SendPlay()) {
   308       return NS_ERROR_FAILURE;
   309     }
   310   } else {
   311     nsresult rv = NS_DispatchToMainThread(
   312                     new SendIPCEvent(this, SendPlayEvent));
   313     NS_ENSURE_SUCCESS(rv, rv);
   314   }
   316   return NS_OK;
   317 }
   319 NS_IMETHODIMP
   320 RtspControllerChild::Pause(void)
   321 {
   322   LOG(("RtspControllerChild::Pause()"));
   324   if (NS_IsMainThread()) {
   325     if (!OKToSendIPC() || !SendPause()) {
   326       return NS_ERROR_FAILURE;
   327     }
   328   } else {
   329     nsresult rv = NS_DispatchToMainThread(
   330                     new SendIPCEvent(this, SendPauseEvent));
   331     NS_ENSURE_SUCCESS(rv, rv);
   332   }
   334   return NS_OK;
   335 }
   337 NS_IMETHODIMP
   338 RtspControllerChild::Resume(void)
   339 {
   340   LOG(("RtspControllerChild::Resume()"));
   341   NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
   343   if (!--mSuspendCount) {
   344     if (NS_IsMainThread()) {
   345       if (!OKToSendIPC() || !SendResume()) {
   346         return NS_ERROR_FAILURE;
   347       }
   348     } else {
   349       nsresult rv = NS_DispatchToMainThread(
   350                       new SendIPCEvent(this, SendResumeEvent));
   351       NS_ENSURE_SUCCESS(rv, rv);
   352     }
   353   }
   355   return NS_OK;
   356 }
   358 NS_IMETHODIMP
   359 RtspControllerChild::Suspend(void)
   360 {
   361   LOG(("RtspControllerChild::Suspend()"));
   363   if (!mSuspendCount++) {
   364     if (NS_IsMainThread()) {
   365       if (!OKToSendIPC() || !SendSuspend()) {
   366         return NS_ERROR_FAILURE;
   367       }
   368     } else {
   369       nsresult rv = NS_DispatchToMainThread(
   370                       new SendIPCEvent(this, SendSuspendEvent));
   371       NS_ENSURE_SUCCESS(rv, rv);
   372     }
   373   }
   375   return NS_OK;
   376 }
   378 NS_IMETHODIMP
   379 RtspControllerChild::Seek(uint64_t seekTimeUs)
   380 {
   381   LOG(("RtspControllerChild::Seek() %llu", seekTimeUs));
   383   if (NS_IsMainThread()) {
   384     if (!OKToSendIPC() || !SendSeek(seekTimeUs)) {
   385       return NS_ERROR_FAILURE;
   386     }
   387   } else {
   388     nsresult rv = NS_DispatchToMainThread(
   389                     new SendIPCEvent(this, SendSeekEvent, seekTimeUs));
   390     NS_ENSURE_SUCCESS(rv, rv);
   391   }
   393   return NS_OK;
   394 }
   396 NS_IMETHODIMP
   397 RtspControllerChild::Stop()
   398 {
   399   LOG(("RtspControllerChild::Stop()"));
   401   if (NS_IsMainThread()) {
   402     if (!OKToSendIPC() || !SendStop()) {
   403       return NS_ERROR_FAILURE;
   404     }
   405     DisallowIPC();
   406   } else {
   407     nsresult rv = NS_DispatchToMainThread(
   408                     new SendIPCEvent(this, SendStopEvent));
   409     NS_ENSURE_SUCCESS(rv, rv);
   410   }
   412   return NS_OK;
   413 }
   415 NS_IMETHODIMP
   416 RtspControllerChild::GetTotalTracks(uint8_t *aTracks)
   417 {
   418   NS_ENSURE_ARG_POINTER(aTracks);
   419   *aTracks = kRtspTotalTracks;
   420   if (mTotalTracks) {
   421     *aTracks = mTotalTracks;
   422   }
   423   LOG(("RtspControllerChild::GetTracks() %d", *aTracks));
   424   return NS_OK;
   425 }
   427 //-----------------------------------------------------------------------------
   428 // RtspControllerChild::nsIStreamingProtocolListener
   429 //-----------------------------------------------------------------------------
   430 NS_IMETHODIMP
   431 RtspControllerChild::OnMediaDataAvailable(uint8_t index,
   432                                           const nsACString & data,
   433                                           uint32_t length,
   434                                           uint32_t offset,
   435                                           nsIStreamingProtocolMetaData *meta)
   436 {
   437   LOG(("RtspControllerChild::OnMediaDataAvailable()"));
   438   return NS_ERROR_NOT_IMPLEMENTED;
   439 }
   441 NS_IMETHODIMP
   442 RtspControllerChild::OnConnected(uint8_t index,
   443                                  nsIStreamingProtocolMetaData *meta)
   445 {
   446   LOG(("RtspControllerChild::OnConnected()"));
   447   return NS_ERROR_NOT_IMPLEMENTED;
   448 }
   450 NS_IMETHODIMP
   451 RtspControllerChild::OnDisconnected(uint8_t index,
   452                                     nsresult reason)
   453 {
   454   LOG(("RtspControllerChild::OnDisconnected() reason = 0x%x", reason));
   455   return NS_ERROR_NOT_IMPLEMENTED;
   456 }
   458 //-----------------------------------------------------------------------------
   459 // RtspControllerChild::nsIStreamingProtocoController
   460 //-----------------------------------------------------------------------------
   461 NS_IMETHODIMP
   462 RtspControllerChild::Init(nsIURI *aURI)
   463 {
   464   nsresult rv;
   466   if (!aURI) {
   467     LOG(("RtspControllerChild::Init() - invalid URI"));
   468     return NS_ERROR_NOT_INITIALIZED;
   469   }
   471   nsAutoCString host;
   472   int32_t port = -1;
   474   rv = aURI->GetAsciiHost(host);
   475   if (NS_FAILED(rv)) return rv;
   477   // Reject the URL if it doesn't specify a host
   478   if (host.IsEmpty())
   479     return NS_ERROR_MALFORMED_URI;
   481   rv = aURI->GetPort(&port);
   482   if (NS_FAILED(rv)) return rv;
   484   rv = aURI->GetAsciiSpec(mSpec);
   485   if (NS_FAILED(rv)) return rv;
   487   if (!strncmp(mSpec.get(), "rtsp:", 5) == 0)
   488     return NS_ERROR_UNEXPECTED;
   490   mURI = aURI;
   492   return NS_OK;
   493 }
   495 NS_IMETHODIMP
   496 RtspControllerChild::AsyncOpen(nsIStreamingProtocolListener *aListener)
   497 {
   498   LOG(("RtspControllerChild::AsyncOpen()"));
   499   if (!aListener) {
   500     LOG(("RtspControllerChild::AsyncOpen() - invalid listener"));
   501     return NS_ERROR_NOT_INITIALIZED;
   502   }
   503   mListener = aListener;
   505   if (!mChannel) {
   506     LOG(("RtspControllerChild::AsyncOpen() - invalid URI"));
   507     return NS_ERROR_NOT_INITIALIZED;
   508   }
   510   nsCOMPtr<nsIURI> uri;
   511   URIParams uriParams;
   512   mChannel->GetURI(getter_AddRefs(uri));
   513   if (!uri) {
   514     LOG(("RtspControllerChild::AsyncOpen() - invalid URI"));
   515     return NS_ERROR_NOT_INITIALIZED;
   516   }
   517   SerializeURI(uri, uriParams);
   519   if (!OKToSendIPC() || !SendAsyncOpen(uriParams)) {
   520     return NS_ERROR_FAILURE;
   521   }
   522   return NS_OK;
   523 }
   525 } // namespace net
   526 } // namespace mozilla

mercurial