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