xref: /aosp_15_r20/external/webrtc/pc/jsep_transport_collection.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2021 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef PC_JSEP_TRANSPORT_COLLECTION_H_
12 #define PC_JSEP_TRANSPORT_COLLECTION_H_
13 
14 #include <functional>
15 #include <map>
16 #include <memory>
17 #include <string>
18 #include <utility>
19 #include <vector>
20 
21 #include "api/jsep.h"
22 #include "api/peer_connection_interface.h"
23 #include "api/sequence_checker.h"
24 #include "pc/jsep_transport.h"
25 #include "pc/session_description.h"
26 #include "rtc_base/checks.h"
27 #include "rtc_base/system/no_unique_address.h"
28 #include "rtc_base/thread_annotations.h"
29 
30 namespace webrtc {
31 
32 // This class manages information about RFC 8843 BUNDLE bundles
33 // in SDP descriptions.
34 
35 // This is a work-in-progress. Planned steps:
36 // 1) Move all Bundle-related data structures from JsepTransport
37 //    into this class.
38 // 2) Move all Bundle-related functions into this class.
39 // 3) Move remaining Bundle-related logic into this class.
40 //    Make data members private.
41 // 4) Refine interface to have comprehensible semantics.
42 // 5) Add unit tests.
43 // 6) Change the logic to do what's right.
44 class BundleManager {
45  public:
BundleManager(PeerConnectionInterface::BundlePolicy bundle_policy)46   explicit BundleManager(PeerConnectionInterface::BundlePolicy bundle_policy)
47       : bundle_policy_(bundle_policy) {
48     // Allow constructor to be called on a different thread.
49     sequence_checker_.Detach();
50   }
bundle_groups()51   const std::vector<std::unique_ptr<cricket::ContentGroup>>& bundle_groups()
52       const {
53     RTC_DCHECK_RUN_ON(&sequence_checker_);
54     return bundle_groups_;
55   }
56   // Lookup a bundle group by a member mid name.
57   const cricket::ContentGroup* LookupGroupByMid(const std::string& mid) const;
58   cricket::ContentGroup* LookupGroupByMid(const std::string& mid);
59   // Returns true if the MID is the first item of a group, or if
60   // the MID is not a member of a group.
61   bool IsFirstMidInGroup(const std::string& mid) const;
62   // Update the groups description. This completely replaces the group
63   // description with the one from the SessionDescription.
64   void Update(const cricket::SessionDescription* description, SdpType type);
65   // Delete a MID from the group that contains it.
66   void DeleteMid(const cricket::ContentGroup* bundle_group,
67                  const std::string& mid);
68   // Delete a group.
69   void DeleteGroup(const cricket::ContentGroup* bundle_group);
70   // Roll back to previous stable state.
71   void Rollback();
72   // Commit current bundle groups.
73   void Commit();
74 
75  private:
76   // Recalculate established_bundle_groups_by_mid_ from bundle_groups_.
77   void RefreshEstablishedBundleGroupsByMid() RTC_RUN_ON(sequence_checker_);
78 
79   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
80   PeerConnectionInterface::BundlePolicy bundle_policy_;
81   std::vector<std::unique_ptr<cricket::ContentGroup>> bundle_groups_
82       RTC_GUARDED_BY(sequence_checker_);
83   std::vector<std::unique_ptr<cricket::ContentGroup>> stable_bundle_groups_
84       RTC_GUARDED_BY(sequence_checker_);
85   std::map<std::string, cricket::ContentGroup*>
86       established_bundle_groups_by_mid_;
87 };
88 
89 // This class keeps the mapping of MIDs to transports.
90 // It is pulled out here because a lot of the code that deals with
91 // bundles end up modifying this map, and the two need to be consistent;
92 // the managers may merge.
93 class JsepTransportCollection {
94  public:
JsepTransportCollection(std::function<bool (const std::string & mid,cricket::JsepTransport * transport)> map_change_callback,std::function<void ()> state_change_callback)95   JsepTransportCollection(std::function<bool(const std::string& mid,
96                                              cricket::JsepTransport* transport)>
97                               map_change_callback,
98                           std::function<void()> state_change_callback)
99       : map_change_callback_(map_change_callback),
100         state_change_callback_(state_change_callback) {
101     // Allow constructor to be called on a different thread.
102     sequence_checker_.Detach();
103   }
104 
105   void RegisterTransport(const std::string& mid,
106                          std::unique_ptr<cricket::JsepTransport> transport);
107   // Returns all transports, including those not currently mapped to any MID
108   // because they're being kept alive in case of rollback.
109   std::vector<cricket::JsepTransport*> Transports();
110   // Only returns transports currently mapped to a MID.
111   std::vector<cricket::JsepTransport*> ActiveTransports();
112   void DestroyAllTransports();
113   // Lookup a JsepTransport by the MID that was used to register it.
114   cricket::JsepTransport* GetTransportByName(const std::string& mid);
115   const cricket::JsepTransport* GetTransportByName(
116       const std::string& mid) const;
117   // Lookup a JsepTransport by any MID that refers to it.
118   cricket::JsepTransport* GetTransportForMid(const std::string& mid);
119   const cricket::JsepTransport* GetTransportForMid(
120       const std::string& mid) const;
121   cricket::JsepTransport* GetTransportForMid(absl::string_view mid);
122   const cricket::JsepTransport* GetTransportForMid(absl::string_view mid) const;
123   // Set transport for a MID. This may destroy a transport if it is no
124   // longer in use.
125   bool SetTransportForMid(const std::string& mid,
126                           cricket::JsepTransport* jsep_transport);
127   // Remove a transport for a MID. This may destroy a transport if it is
128   // no longer in use.
129   void RemoveTransportForMid(const std::string& mid);
130   // Roll back to previous stable mid-to-transport mappings.
131   bool RollbackTransports();
132   // Commit pending mid-transport mappings (rollback is no longer possible),
133   // and destroy unused transports because we know now we'll never need them
134   // again.
135   void CommitTransports();
136 
137  private:
138   // Returns true if any mid currently maps to this transport.
139   bool TransportInUse(cricket::JsepTransport* jsep_transport) const;
140 
141   // Returns true if any mid in the last stable mapping maps to this transport,
142   // meaning it should be kept alive in case of rollback.
143   bool TransportNeededForRollback(cricket::JsepTransport* jsep_transport) const;
144 
145   // Destroy a transport if it's no longer in use. This includes whether it
146   // will be needed in case of rollback.
147   void MaybeDestroyJsepTransport(cricket::JsepTransport* transport);
148 
149   // Destroys all transports that are no longer in use.
150   void DestroyUnusedTransports();
151 
152   bool IsConsistent();  // For testing only: Verify internal structure.
153 
154   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
155   // This member owns the JSEP transports.
156   std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
157       jsep_transports_by_name_ RTC_GUARDED_BY(sequence_checker_);
158 
159   // This keeps track of the mapping between media section
160   // (BaseChannel/SctpTransport) and the JsepTransport underneath.
161   std::map<std::string, cricket::JsepTransport*> mid_to_transport_
162       RTC_GUARDED_BY(sequence_checker_);
163   // A snapshot of mid_to_transport_ at the last stable state. Used for
164   // rollback.
165   std::map<std::string, cricket::JsepTransport*> stable_mid_to_transport_
166       RTC_GUARDED_BY(sequence_checker_);
167   // Callback used to inform subscribers of altered transports.
168   const std::function<bool(const std::string& mid,
169                            cricket::JsepTransport* transport)>
170       map_change_callback_;
171   // Callback used to inform subscribers of possibly altered state.
172   const std::function<void()> state_change_callback_;
173 };
174 
175 }  // namespace webrtc
176 
177 #endif  // PC_JSEP_TRANSPORT_COLLECTION_H_
178