Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/webrtc/jsapi/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 17 kB image not shown  

Quelle  MediaTransportHandlerIPC.cpp   Sprache: C

 
/* 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/. */


#include "MediaTransportHandlerIPC.h"
#include "mozilla/dom/MediaTransportChild.h"
#include "nsThreadUtils.h"
#include "mozilla/net/SocketProcessBridgeChild.h"
#include "mozilla/RefPtr.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "common/browser_logging/CSFLog.h"

namespace mozilla {

static const char* mthipcLogTag = "MediaTransportHandler";
#ifdef LOGTAG
#  undef LOGTAG
#endif
#define LOGTAG mthipcLogTag

MediaTransportHandlerIPC::MediaTransportHandlerIPC(
    nsISerialEventTarget* aCallbackThread)
    : MediaTransportHandler(aCallbackThread) {}

MediaTransportHandlerIPC::~MediaTransportHandlerIPC() = default;

void MediaTransportHandlerIPC::Initialize() {
  using EndpointPromise =
      MozPromise<mozilla::ipc::Endpoint<mozilla::dom::PMediaTransportChild>,
                 nsCString, true>;
  mInitPromise =
      net::SocketProcessBridgeChild::GetSocketProcessBridge()
          ->Then(
              GetCurrentSerialEventTarget(), __func__,
              [](const RefPtr<net::SocketProcessBridgeChild>& aBridge) {
                mozilla::ipc::Endpoint<mozilla::dom::PMediaTransportParent>
                    parentEndpoint;
                mozilla::ipc::Endpoint<mozilla::dom::PMediaTransportChild>
                    childEndpoint;
                mozilla::dom::PMediaTransport::CreateEndpoints(&parentEndpoint,
                                                               &childEndpoint);

                if (!aBridge || !aBridge->SendInitMediaTransport(
                                    std::move(parentEndpoint))) {
                  NS_WARNING(
                      "MediaTransportHandlerIPC async init failed! Webrtc "
                      "networking "
                      "will not work!");
                  return EndpointPromise::CreateAndReject(
                      nsCString("SendInitMediaTransport failed!"), __func__);
                }

                return EndpointPromise::CreateAndResolve(
                    std::move(childEndpoint), __func__);
              },
              [](const nsCString& aError) {
                return EndpointPromise::CreateAndReject(aError, __func__);
              })
          ->Then(
              mCallbackThread, __func__,
              [this, self = RefPtr<MediaTransportHandlerIPC>(this)](
                  mozilla::ipc::Endpoint<mozilla::dom::PMediaTransportChild>&&
                      aEndpoint) {
                RefPtr<MediaTransportChild> child =
                    new MediaTransportChild(this);
                aEndpoint.Bind(child);
                mChild = child;

                CSFLogDebug(LOGTAG, "%s Init done", __func__);
                return InitPromise::CreateAndResolve(true, __func__);
              },
              [=](const nsCString& aError) {
                CSFLogError(
                    LOGTAG,
                    "MediaTransportHandlerIPC async init failed! Webrtc "
                    "networking will not work! Error was %s",
                    aError.get());
                NS_WARNING(
                    "MediaTransportHandlerIPC async init failed! Webrtc "
                    "networking "
                    "will not work!");
                return InitPromise::CreateAndReject(aError, __func__);
              });
}

RefPtr<MediaTransportHandler::IceLogPromise>
MediaTransportHandlerIPC::GetIceLog(const nsCString& aPattern) {
  return mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /* dummy */) {
        if (!mChild) {
          return IceLogPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
        }
        // Compiler has trouble deducing the return type here for some reason,
        // so we use a temp variable as a hint.
        // SendGetIceLog _almost_ returns an IceLogPromise; the reject value
        // differs (ipc::ResponseRejectReason vs nsresult) so we need to
        // convert.
        RefPtr<IceLogPromise> promise = mChild->SendGetIceLog(aPattern)->Then(
            mCallbackThread, __func__,
            [](WebrtcGlobalLog&& aLogLines) {
              return IceLogPromise::CreateAndResolve(std::move(aLogLines),
                                                     __func__);
            },
            [](ipc::ResponseRejectReason aReason) {
              return IceLogPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
            });
        return promise;
      },
      [](const nsCString& aError) {
        return IceLogPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
      });
}

void MediaTransportHandlerIPC::ClearIceLog() {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendClearIceLog();
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::EnterPrivateMode() {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendEnterPrivateMode();
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::ExitPrivateMode() {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendExitPrivateMode();
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::CreateIceCtx(const std::string& aName) {
  CSFLogDebug(LOGTAG, "MediaTransportHandlerIPC::CreateIceCtx start");

  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          CSFLogDebug(LOGTAG, "%s starting", __func__);
          if (NS_WARN_IF(!mChild->SendCreateIceCtx(aName))) {
            CSFLogError(LOGTAG, "%s failed!", __func__);
          }
        }
      },
      [](const nsCString& aError) {});
}

nsresult MediaTransportHandlerIPC::SetIceConfig(
    const nsTArray<dom::RTCIceServer>& aIceServers,
    dom::RTCIceTransportPolicy aIcePolicy) {
  // Run some validation on this side of the IPC boundary so we can return
  // errors synchronously. We don't actually use the results. It might make
  // sense to move this check to PeerConnection and have this API take the
  // converted form, but we would need to write IPC serialization code for
  // the NrIce*Server types.
  std::vector<NrIceStunServer> stunServers;
  std::vector<NrIceTurnServer> turnServers;
  nsresult rv = ConvertIceServers(aIceServers, &stunServers, &turnServers);
  if (NS_FAILED(rv)) {
    return rv;
  }

  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, iceServers = aIceServers.Clone(),
       self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          if (NS_WARN_IF(!mChild->SendSetIceConfig(std::move(iceServers),
                                                   aIcePolicy))) {
            CSFLogError(LOGTAG, "%s failed!", __func__);
          }
        }
      },
      [](const nsCString& aError) {});

  return NS_OK;
}

void MediaTransportHandlerIPC::Destroy() {
  if (mChild) {
    mChild->Shutdown();
    mCallbackThread->Dispatch(NS_NewRunnableFunction(
        __func__, [child = std::move(mChild)]() { child->Close(); }));
  }
  delete this;
}

// We will probably be able to move the proxy lookup stuff into
// this class once we move mtransport to its own process.
void MediaTransportHandlerIPC::SetProxyConfig(
    NrSocketProxyConfig&& aProxyConfig) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [aProxyConfig = std::move(aProxyConfig), this,
       self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) mutable {
        if (mChild) {
          mChild->SendSetProxyConfig(aProxyConfig.GetConfig());
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::EnsureProvisionalTransport(
    const std::string& aTransportId, const std::string& aLocalUfrag,
    const std::string& aLocalPwd, int aComponentCount) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendEnsureProvisionalTransport(aTransportId, aLocalUfrag,
                                                 aLocalPwd, aComponentCount);
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::SetTargetForDefaultLocalAddressLookup(
    const std::string& aTargetIp, uint16_t aTargetPort) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendSetTargetForDefaultLocalAddressLookup(aTargetIp,
                                                            aTargetPort);
        }
      },
      [](const nsCString& aError) {});
}

// We set default-route-only as late as possible because it depends on what
// capture permissions have been granted on the window, which could easily
// change between Init (ie; when the PC is created) and StartIceGathering
// (ie; when we set the local description).
void MediaTransportHandlerIPC::StartIceGathering(
    bool aDefaultRouteOnly, bool aObfuscateHostAddresses,
    // TODO(bug 1522205): It probably makes sense to look this up internally
    const nsTArray<NrIceStunAddr>& aStunAddrs) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, stunAddrs = aStunAddrs.Clone(),
       self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendStartIceGathering(aDefaultRouteOnly,
                                        aObfuscateHostAddresses, stunAddrs);
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::ActivateTransport(
    const std::string& aTransportId, const std::string& aLocalUfrag,
    const std::string& aLocalPwd, size_t aComponentCount,
    const std::string& aUfrag, const std::string& aPassword,
    const nsTArray<uint8_t>& aKeyDer, const nsTArray<uint8_t>& aCertDer,
    SSLKEAType aAuthType, bool aDtlsClient, const DtlsDigestList& aDigests,
    bool aPrivacyRequested) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, keyDer = aKeyDer.Clone(), certDer = aCertDer.Clone(),
       self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendActivateTransport(aTransportId, aLocalUfrag, aLocalPwd,
                                        aComponentCount, aUfrag, aPassword,
                                        keyDer, certDer, aAuthType, aDtlsClient,
                                        aDigests, aPrivacyRequested);
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::RemoveTransportsExcept(
    const std::set<std::string>& aTransportIds) {
  std::vector<std::string> transportIds(aTransportIds.begin(),
                                        aTransportIds.end());
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendRemoveTransportsExcept(transportIds);
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::StartIceChecks(
    bool aIsControlling, const std::vector<std::string>& aIceOptions) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendStartIceChecks(aIsControlling, aIceOptions);
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::SendPacket(const std::string& aTransportId,
                                          MediaPacket&& aPacket) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [this, self = RefPtr<MediaTransportHandlerIPC>(this), aTransportId,
       aPacket = std::move(aPacket)](bool /*dummy*/) mutable {
        if (mChild) {
          mChild->SendSendPacket(aTransportId, aPacket);
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::AddIceCandidate(
    const std::string& aTransportId, const std::string& aCandidate,
    const std::string& aUfrag, const std::string& aObfuscatedAddress) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendAddIceCandidate(aTransportId, aCandidate, aUfrag,
                                      aObfuscatedAddress);
        }
      },
      [](const nsCString& aError) {});
}

void MediaTransportHandlerIPC::UpdateNetworkState(bool aOnline) {
  mInitPromise->Then(
      mCallbackThread, __func__,
      [=, self = RefPtr<MediaTransportHandlerIPC>(this)](bool /*dummy*/) {
        if (mChild) {
          mChild->SendUpdateNetworkState(aOnline);
        }
      },
      [](const nsCString& aError) {});
}

RefPtr<dom::RTCStatsPromise> MediaTransportHandlerIPC::GetIceStats(
    const std::string& aTransportId, DOMHighResTimeStamp aNow) {
  using IPCPromise = dom::PMediaTransportChild::GetIceStatsPromise;
  return mInitPromise
      ->Then(mCallbackThread, __func__,
             [aTransportId, aNow, this, self = RefPtr(this)](
                 const InitPromise::ResolveOrRejectValue& aValue) {
               if (aValue.IsReject()) {
                 return IPCPromise::CreateAndResolve(
                     MakeUnique<dom::RTCStatsCollection>(),
                     "MediaTransportHandlerIPC::GetIceStats_1");
               }
               if (!mChild) {
                 return IPCPromise::CreateAndResolve(
                     MakeUnique<dom::RTCStatsCollection>(),
                     "MediaTransportHandlerIPC::GetIceStats_1");
               }
               return mChild->SendGetIceStats(aTransportId, aNow);
             })
      ->Then(mCallbackThread, __func__,
             [](IPCPromise::ResolveOrRejectValue&& aValue) {
               if (aValue.IsReject()) {
                 return dom::RTCStatsPromise::CreateAndResolve(
                     MakeUnique<dom::RTCStatsCollection>(),
                     "MediaTransportHandlerIPC::GetIceStats_2");
               }
               return dom::RTCStatsPromise::CreateAndResolve(
                   std::move(aValue.ResolveValue()),
                   "MediaTransportHandlerIPC::GetIceStats_2");
             });
}

MediaTransportChild::MediaTransportChild(MediaTransportHandlerIPC* aUser)
    : mMutex("MediaTransportChild"), mUser(aUser) {}

MediaTransportChild::~MediaTransportChild() = default;

mozilla::ipc::IPCResult MediaTransportChild::RecvOnCandidate(
    const string& transportId, const CandidateInfo& candidateInfo) {
  MutexAutoLock lock(mMutex);
  if (mUser) {
    mUser->OnCandidate(transportId, candidateInfo);
  }
  return ipc::IPCResult::Ok();
}

mozilla::ipc::IPCResult MediaTransportChild::RecvOnAlpnNegotiated(
    const string& alpn) {
  MutexAutoLock lock(mMutex);
  if (mUser) {
    mUser->OnAlpnNegotiated(alpn);
  }
  return ipc::IPCResult::Ok();
}

mozilla::ipc::IPCResult MediaTransportChild::RecvOnGatheringStateChange(
    const string& transportId, const int& state) {
  MutexAutoLock lock(mMutex);
  if (mUser) {
    mUser->OnGatheringStateChange(transportId,
                                  static_cast<dom::RTCIceGathererState>(state));
  }
  return ipc::IPCResult::Ok();
}

mozilla::ipc::IPCResult MediaTransportChild::RecvOnConnectionStateChange(
    const string& transportId, const int& state) {
  MutexAutoLock lock(mMutex);
  if (mUser) {
    mUser->OnConnectionStateChange(
        transportId, static_cast<dom::RTCIceTransportState>(state));
  }
  return ipc::IPCResult::Ok();
}

mozilla::ipc::IPCResult MediaTransportChild::RecvOnPacketReceived(
    const string& transportId, const MediaPacket& packet) {
  MutexAutoLock lock(mMutex);
  if (mUser) {
    mUser->OnPacketReceived(transportId, packet);
  }
  return ipc::IPCResult::Ok();
}

mozilla::ipc::IPCResult MediaTransportChild::RecvOnEncryptedSending(
    const string& transportId, const MediaPacket& packet) {
  MutexAutoLock lock(mMutex);
  if (mUser) {
    mUser->OnEncryptedSending(transportId, packet);
  }
  return ipc::IPCResult::Ok();
}

mozilla::ipc::IPCResult MediaTransportChild::RecvOnStateChange(
    const string& transportId, const int& state) {
  MutexAutoLock lock(mMutex);
  if (mUser) {
    mUser->OnStateChange(transportId,
                         static_cast<TransportLayer::State>(state));
  }
  return ipc::IPCResult::Ok();
}

mozilla::ipc::IPCResult MediaTransportChild::RecvOnRtcpStateChange(
    const string& transportId, const int& state) {
  MutexAutoLock lock(mMutex);
  if (mUser) {
    mUser->OnRtcpStateChange(transportId,
                             static_cast<TransportLayer::State>(state));
  }
  return ipc::IPCResult::Ok();
}

void MediaTransportChild::Shutdown() {
  MutexAutoLock lock(mMutex);
  mUser = nullptr;
}

}  // namespace mozilla

Messung V0.5
C=90 H=96 G=93

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.