RTCStatsIdGenerator.cpp (3031B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 5 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 6 7 #include "RTCStatsIdGenerator.h" 8 9 #include "RTCStatsReport.h" 10 #include "WebrtcGlobal.h" 11 #include "mozilla/RandomNum.h" 12 13 namespace mozilla { 14 15 RTCStatsIdGenerator::RTCStatsIdGenerator() 16 : mSalt(RandomUint64().valueOr(0xa5a5a5a5)), mCounter(0) {} 17 18 void RTCStatsIdGenerator::RewriteIds( 19 nsTArray<UniquePtr<dom::RTCStatsCollection>> aFromStats, 20 dom::RTCStatsCollection* aIntoReport) { 21 // Rewrite an Optional id 22 auto rewriteId = [&](dom::Optional<nsString>& id) { 23 if (id.WasPassed()) { 24 id.Value() = Id(id.Value()); 25 } 26 }; 27 28 auto rewriteIds = [&](auto& aList, auto... aParam) { 29 for (auto& stat : aList) { 30 (rewriteId(stat.*aParam), ...); 31 } 32 }; 33 34 // Involves a lot of copying, since webidl dictionaries don't have 35 // move semantics. Oh well. 36 37 // Create a temporary to avoid double-rewriting any stats already in 38 // aIntoReport. 39 auto stats = MakeUnique<dom::RTCStatsCollection>(); 40 dom::FlattenStats(std::move(aFromStats), stats.get()); 41 42 using S = dom::RTCStats; 43 using ICPS = dom::RTCIceCandidatePairStats; 44 using RSS = dom::RTCRtpStreamStats; 45 using IRSS = dom::RTCInboundRtpStreamStats; 46 using ORSS = dom::RTCOutboundRtpStreamStats; 47 using RIRSS = dom::RTCRemoteInboundRtpStreamStats; 48 using RORSS = dom::RTCRemoteOutboundRtpStreamStats; 49 50 rewriteIds(stats->mIceCandidatePairStats, &S::mId, &ICPS::mLocalCandidateId, 51 &ICPS::mRemoteCandidateId); 52 rewriteIds(stats->mIceCandidateStats, &S::mId); 53 rewriteIds(stats->mInboundRtpStreamStats, &S::mId, &IRSS::mRemoteId, 54 &RSS::mCodecId); 55 rewriteIds(stats->mOutboundRtpStreamStats, &S::mId, &ORSS::mRemoteId, 56 &RSS::mCodecId); 57 rewriteIds(stats->mRemoteInboundRtpStreamStats, &S::mId, &RIRSS::mLocalId, 58 &RSS::mCodecId); 59 rewriteIds(stats->mRemoteOutboundRtpStreamStats, &S::mId, &RORSS::mLocalId, 60 &RSS::mCodecId); 61 rewriteIds(stats->mCodecStats, &S::mId); 62 rewriteIds(stats->mRtpContributingSourceStats, &S::mId); 63 rewriteIds(stats->mTrickledIceCandidateStats, &S::mId); 64 rewriteIds(stats->mDataChannelStats, &S::mId); 65 66 dom::MergeStats(std::move(stats), aIntoReport); 67 } 68 69 nsString RTCStatsIdGenerator::Id(const nsString& aKey) { 70 if (!aKey.Length()) { 71 MOZ_ASSERT(aKey.Length(), "Stats IDs should never be empty."); 72 return aKey; 73 } 74 if (mAllocated.find(aKey) == mAllocated.end()) { 75 mAllocated[aKey] = Generate(); 76 } 77 return mAllocated[aKey]; 78 } 79 80 nsString RTCStatsIdGenerator::Generate() { 81 auto random = RandomUint64().valueOr(0x1a22); 82 auto idNum = static_cast<uint32_t>(mSalt ^ ((mCounter++ << 16) | random)); 83 nsString id; 84 id.AppendInt(idNum, 16); // Append as hex 85 return id; 86 } 87 88 } // namespace mozilla