1/*
2 * libjingle
3 * Copyright 2012 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 *  1. Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 *  2. Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 *  3. The name of the author may not be used to endorse or promote products
14 *     derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28// This file contains structures used for retrieving statistics from an ongoing
29// libjingle session.
30
31#ifndef TALK_APP_WEBRTC_STATSTYPES_H_
32#define TALK_APP_WEBRTC_STATSTYPES_H_
33
34#include <algorithm>
35#include <list>
36#include <map>
37#include <string>
38
39#include "webrtc/base/basictypes.h"
40#include "webrtc/base/common.h"
41#include "webrtc/base/refcount.h"
42#include "webrtc/base/scoped_ptr.h"
43#include "webrtc/base/linked_ptr.h"
44#include "webrtc/base/scoped_ref_ptr.h"
45#include "webrtc/base/stringencode.h"
46#include "webrtc/base/thread_checker.h"
47
48namespace webrtc {
49
50class StatsReport {
51 public:
52  // Indicates whether a track is for sending or receiving.
53  // Used in reports for audio/video tracks.
54  enum Direction {
55    kSend = 0,
56    kReceive,
57  };
58
59  enum StatsType {
60    // StatsReport types.
61    // A StatsReport of |type| = "googSession" contains overall information
62    // about the thing libjingle calls a session (which may contain one
63    // or more RTP sessions.
64    kStatsReportTypeSession,
65
66    // A StatsReport of |type| = "googTransport" contains information
67    // about a libjingle "transport".
68    kStatsReportTypeTransport,
69
70    // A StatsReport of |type| = "googComponent" contains information
71    // about a libjingle "channel" (typically, RTP or RTCP for a transport).
72    // This is intended to be the same thing as an ICE "Component".
73    kStatsReportTypeComponent,
74
75    // A StatsReport of |type| = "googCandidatePair" contains information
76    // about a libjingle "connection" - a single source/destination port pair.
77    // This is intended to be the same thing as an ICE "candidate pair".
78    kStatsReportTypeCandidatePair,
79
80    // A StatsReport of |type| = "VideoBWE" is statistics for video Bandwidth
81    // Estimation, which is global per-session.  The |id| field is "bweforvideo"
82    // (will probably change in the future).
83    kStatsReportTypeBwe,
84
85    // A StatsReport of |type| = "ssrc" is statistics for a specific rtp stream.
86    // The |id| field is the SSRC in decimal form of the rtp stream.
87    kStatsReportTypeSsrc,
88
89    // A StatsReport of |type| = "remoteSsrc" is statistics for a specific
90    // rtp stream, generated by the remote end of the connection.
91    kStatsReportTypeRemoteSsrc,
92
93    // A StatsReport of |type| = "googTrack" is statistics for a specific media
94    // track. The |id| field is the track id.
95    kStatsReportTypeTrack,
96
97    // A StatsReport of |type| = "localcandidate" or "remotecandidate" is
98    // attributes on a specific ICE Candidate. It links to its connection pair
99    // by candidate id. The string value is taken from
100    // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
101    kStatsReportTypeIceLocalCandidate,
102    kStatsReportTypeIceRemoteCandidate,
103
104    // A StatsReport of |type| = "googCertificate" contains an SSL certificate
105    // transmitted by one of the endpoints of this connection.  The |id| is
106    // controlled by the fingerprint, and is used to identify the certificate in
107    // the Channel stats (as "googLocalCertificateId" or
108    // "googRemoteCertificateId") and in any child certificates (as
109    // "googIssuerId").
110    kStatsReportTypeCertificate,
111
112    // A StatsReport of |type| = "datachannel" with statistics for a
113    // particular DataChannel.
114    kStatsReportTypeDataChannel,
115  };
116
117  enum StatsValueName {
118    kStatsValueNameActiveConnection,
119    kStatsValueNameAudioInputLevel,
120    kStatsValueNameAudioOutputLevel,
121    kStatsValueNameBytesReceived,
122    kStatsValueNameBytesSent,
123    kStatsValueNameCodecImplementationName,
124    kStatsValueNameDataChannelId,
125    kStatsValueNamePacketsLost,
126    kStatsValueNamePacketsReceived,
127    kStatsValueNamePacketsSent,
128    kStatsValueNameProtocol,
129    kStatsValueNameReceiving,
130    kStatsValueNameSelectedCandidatePairId,
131    kStatsValueNameSsrc,
132    kStatsValueNameState,
133    kStatsValueNameTransportId,
134
135    // Internal StatsValue names.
136    kStatsValueNameAccelerateRate,
137    kStatsValueNameActualEncBitrate,
138    kStatsValueNameAdaptationChanges,
139    kStatsValueNameAvailableReceiveBandwidth,
140    kStatsValueNameAvailableSendBandwidth,
141    kStatsValueNameAvgEncodeMs,
142    kStatsValueNameBandwidthLimitedResolution,
143    kStatsValueNameBucketDelay,
144    kStatsValueNameCaptureStartNtpTimeMs,
145    kStatsValueNameCandidateIPAddress,
146    kStatsValueNameCandidateNetworkType,
147    kStatsValueNameCandidatePortNumber,
148    kStatsValueNameCandidatePriority,
149    kStatsValueNameCandidateTransportType,
150    kStatsValueNameCandidateType,
151    kStatsValueNameChannelId,
152    kStatsValueNameCodecName,
153    kStatsValueNameComponent,
154    kStatsValueNameContentName,
155    kStatsValueNameCpuLimitedResolution,
156    kStatsValueNameCurrentDelayMs,
157    kStatsValueNameDecodeMs,
158    kStatsValueNameDecodingCNG,
159    kStatsValueNameDecodingCTN,
160    kStatsValueNameDecodingCTSG,
161    kStatsValueNameDecodingNormal,
162    kStatsValueNameDecodingPLC,
163    kStatsValueNameDecodingPLCCNG,
164    kStatsValueNameDer,
165    kStatsValueNameDtlsCipher,
166    kStatsValueNameEchoCancellationQualityMin,
167    kStatsValueNameEchoDelayMedian,
168    kStatsValueNameEchoDelayStdDev,
169    kStatsValueNameEchoReturnLoss,
170    kStatsValueNameEchoReturnLossEnhancement,
171    kStatsValueNameEncodeUsagePercent,
172    kStatsValueNameExpandRate,
173    kStatsValueNameFingerprint,
174    kStatsValueNameFingerprintAlgorithm,
175    kStatsValueNameFirsReceived,
176    kStatsValueNameFirsSent,
177    kStatsValueNameFrameHeightInput,
178    kStatsValueNameFrameHeightReceived,
179    kStatsValueNameFrameHeightSent,
180    kStatsValueNameFrameRateDecoded,
181    kStatsValueNameFrameRateInput,
182    kStatsValueNameFrameRateOutput,
183    kStatsValueNameFrameRateReceived,
184    kStatsValueNameFrameRateSent,
185    kStatsValueNameFrameWidthInput,
186    kStatsValueNameFrameWidthReceived,
187    kStatsValueNameFrameWidthSent,
188    kStatsValueNameInitiator,
189    kStatsValueNameIssuerId,
190    kStatsValueNameJitterBufferMs,
191    kStatsValueNameJitterReceived,
192    kStatsValueNameLabel,
193    kStatsValueNameLocalAddress,
194    kStatsValueNameLocalCandidateId,
195    kStatsValueNameLocalCandidateType,
196    kStatsValueNameLocalCertificateId,
197    kStatsValueNameMaxDecodeMs,
198    kStatsValueNameMinPlayoutDelayMs,
199    kStatsValueNameNacksReceived,
200    kStatsValueNameNacksSent,
201    kStatsValueNamePlisReceived,
202    kStatsValueNamePlisSent,
203    kStatsValueNamePreemptiveExpandRate,
204    kStatsValueNamePreferredJitterBufferMs,
205    kStatsValueNameRemoteAddress,
206    kStatsValueNameRemoteCandidateId,
207    kStatsValueNameRemoteCandidateType,
208    kStatsValueNameRemoteCertificateId,
209    kStatsValueNameRenderDelayMs,
210    kStatsValueNameRetransmitBitrate,
211    kStatsValueNameRtt,
212    kStatsValueNameSecondaryDecodedRate,
213    kStatsValueNameSendPacketsDiscarded,
214    kStatsValueNameSpeechExpandRate,
215    kStatsValueNameSrtpCipher,
216    kStatsValueNameTargetDelayMs,
217    kStatsValueNameTargetEncBitrate,
218    kStatsValueNameTrackId,
219    kStatsValueNameTransmitBitrate,
220    kStatsValueNameTransportType,
221    kStatsValueNameTypingNoiseState,
222    kStatsValueNameViewLimitedResolution,
223    kStatsValueNameWritable,
224  };
225
226  class IdBase : public rtc::RefCountInterface {
227   public:
228    ~IdBase() override;
229    StatsType type() const;
230
231    // Users of IdBase will be using the Id typedef, which is compatible with
232    // this Equals() function.  It simply calls the protected (and overridden)
233    // Equals() method.
234    bool Equals(const rtc::scoped_refptr<IdBase>& other) const {
235      return Equals(*other.get());
236    }
237
238    virtual std::string ToString() const = 0;
239
240   protected:
241    // Protected since users of the IdBase type will be using the Id typedef.
242    virtual bool Equals(const IdBase& other) const;
243
244    IdBase(StatsType type);  // Only meant for derived classes.
245    const StatsType type_;
246
247    static const char kSeparator = '_';
248  };
249
250  typedef rtc::scoped_refptr<IdBase> Id;
251
252  struct Value {
253    enum Type {
254      kInt,           // int.
255      kInt64,         // int64_t.
256      kFloat,         // float.
257      kString,        // std::string
258      kStaticString,  // const char*.
259      kBool,          // bool.
260      kId,            // Id.
261    };
262
263    Value(StatsValueName name, int64_t value, Type int_type);
264    Value(StatsValueName name, float f);
265    Value(StatsValueName name, const std::string& value);
266    Value(StatsValueName name, const char* value);
267    Value(StatsValueName name, bool b);
268    Value(StatsValueName name, const Id& value);
269
270    ~Value();
271
272    // TODO(tommi): This compares name as well as value...
273    // I think we should only need to compare the value part and
274    // move the name part into a hash map.
275    bool Equals(const Value& other) const;
276
277    // Comparison operators. Return true iff the current instance is of the
278    // correct type and holds the same value.  No conversion is performed so
279    // a string value of "123" is not equal to an int value of 123 and an int
280    // value of 123 is not equal to a float value of 123.0f.
281    // One exception to this is that types kInt and kInt64 can be compared and
282    // kString and kStaticString too.
283    bool operator==(const std::string& value) const;
284    bool operator==(const char* value) const;
285    bool operator==(int64_t value) const;
286    bool operator==(bool value) const;
287    bool operator==(float value) const;
288    bool operator==(const Id& value) const;
289
290    // Getters that allow getting the native value directly.
291    // The caller must know the type beforehand or else hit a check.
292    int int_val() const;
293    int64_t int64_val() const;
294    float float_val() const;
295    const char* static_string_val() const;
296    const std::string& string_val() const;
297    bool bool_val() const;
298    const Id& id_val() const;
299
300    // Returns the string representation of |name|.
301    const char* display_name() const;
302
303    // Converts the native value to a string representation of the value.
304    std::string ToString() const;
305
306    Type type() const { return type_; }
307
308    // TODO(tommi): Move |name| and |display_name| out of the Value struct.
309    const StatsValueName name;
310
311   private:
312    const Type type_;
313    // TODO(tommi): Use C++ 11 union and make value_ const.
314    union InternalType {
315      int int_;
316      int64_t int64_;
317      float float_;
318      bool bool_;
319      std::string* string_;
320      const char* static_string_;
321      Id* id_;
322    } value_;
323
324   private:
325    RTC_DISALLOW_COPY_AND_ASSIGN(Value);
326  };
327
328  // TODO(tommi): Consider using a similar approach to how we store Ids using
329  // scoped_refptr for values.
330  typedef rtc::linked_ptr<Value> ValuePtr;
331  typedef std::map<StatsValueName, ValuePtr> Values;
332
333  // Ownership of |id| is passed to |this|.
334  explicit StatsReport(const Id& id);
335
336  // Factory functions for various types of stats IDs.
337  static Id NewBandwidthEstimationId();
338  static Id NewTypedId(StatsType type, const std::string& id);
339  static Id NewTypedIntId(StatsType type, int id);
340  static Id NewIdWithDirection(
341      StatsType type, const std::string& id, Direction direction);
342  static Id NewCandidateId(bool local, const std::string& id);
343  static Id NewComponentId(
344      const std::string& content_name, int component);
345  static Id NewCandidatePairId(
346      const std::string& content_name, int component, int index);
347
348  const Id& id() const { return id_; }
349  StatsType type() const { return id_->type(); }
350  double timestamp() const { return timestamp_; }
351  void set_timestamp(double t) { timestamp_ = t; }
352  bool empty() const { return values_.empty(); }
353  const Values& values() const { return values_; }
354
355  const char* TypeToString() const;
356
357  void AddString(StatsValueName name, const std::string& value);
358  void AddString(StatsValueName name, const char* value);
359  void AddInt64(StatsValueName name, int64_t value);
360  void AddInt(StatsValueName name, int value);
361  void AddFloat(StatsValueName name, float value);
362  void AddBoolean(StatsValueName name, bool value);
363  void AddId(StatsValueName name, const Id& value);
364
365  const Value* FindValue(StatsValueName name) const;
366
367 private:
368  // The unique identifier for this object.
369  // This is used as a key for this report in ordered containers,
370  // so it must never be changed.
371  const Id id_;
372  double timestamp_;  // Time since 1970-01-01T00:00:00Z in milliseconds.
373  Values values_;
374
375  RTC_DISALLOW_COPY_AND_ASSIGN(StatsReport);
376};
377
378// Typedef for an array of const StatsReport pointers.
379// Ownership of the pointers held by this implementation is assumed to lie
380// elsewhere and lifetime guarantees are made by the implementation that uses
381// this type.  In the StatsCollector, object ownership lies with the
382// StatsCollection class.
383typedef std::vector<const StatsReport*> StatsReports;
384
385// A map from the report id to the report.
386// This class wraps an STL container and provides a limited set of
387// functionality in order to keep things simple.
388class StatsCollection {
389 public:
390  StatsCollection();
391  ~StatsCollection();
392
393  typedef std::list<StatsReport*> Container;
394  typedef Container::iterator iterator;
395  typedef Container::const_iterator const_iterator;
396
397  const_iterator begin() const;
398  const_iterator end() const;
399  size_t size() const;
400
401  // Creates a new report object with |id| that does not already
402  // exist in the list of reports.
403  StatsReport* InsertNew(const StatsReport::Id& id);
404  StatsReport* FindOrAddNew(const StatsReport::Id& id);
405  StatsReport* ReplaceOrAddNew(const StatsReport::Id& id);
406
407  // Looks for a report with the given |id|.  If one is not found, NULL
408  // will be returned.
409  StatsReport* Find(const StatsReport::Id& id);
410
411 private:
412  Container list_;
413  rtc::ThreadChecker thread_checker_;
414};
415
416}  // namespace webrtc
417
418#endif  // TALK_APP_WEBRTC_STATSTYPES_H_
419