Revert "Make negotiationneeded processing in PeerConnection spec compliant."

This reverts commit 1fa06041bcd8a0119e557d16e7b54a9110c5ad03.

Reason for revert: Likely cause for breaking downstream projects

Original change's description:
> Make negotiationneeded processing in PeerConnection spec compliant.
> 
> This CL fixes the problem of misfired negotiationneeded notifications due
> to the lack of a NegotiationNeeded slot and the proper procedure to
> update it.
> 
> 
> Change-Id: Ie273c691f11316c9846606446f6cf838226b5d5c
> Bug: chromium:740501
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131283
> Commit-Queue: Guido Urdaneta <guidou@webrtc.org>
> Reviewed-by: Steve Anton <steveanton@webrtc.org>
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#27594}

TBR=steveanton@webrtc.org,magjed@webrtc.org,sakal@webrtc.org,hbos@webrtc.org,guidou@webrtc.org

Change-Id: Iad7b7d4e37227fa6a76ff830160ca3da9dbe4719
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:740501
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132761
Reviewed-by: Jeroen de Borst <jeroendb@webrtc.org>
Commit-Queue: Jeroen de Borst <jeroendb@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27599}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 749f77c..e7a1a11 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -698,15 +698,6 @@
   }
 }
 
-const ContentInfo* FindTransceiverMSection(
-    RtpTransceiverProxyWithInternal<RtpTransceiver>* transceiver,
-    const SessionDescriptionInterface* session_description) {
-  return transceiver->mid()
-             ? session_description->description()->GetContentByName(
-                   *transceiver->mid())
-             : nullptr;
-}
-
 }  // namespace
 
 // Upon completion, posts a task to execute the callback of the
@@ -1263,7 +1254,7 @@
   }
 
   stats_->AddStream(local_stream);
-  UpdateNegotiationNeeded();
+  Observer()->OnRenegotiationNeeded();
   return true;
 }
 
@@ -1293,7 +1284,7 @@
   if (IsClosed()) {
     return;
   }
-  UpdateNegotiationNeeded();
+  Observer()->OnRenegotiationNeeded();
 }
 
 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
@@ -1322,7 +1313,7 @@
       (IsUnifiedPlan() ? AddTrackUnifiedPlan(track, stream_ids)
                        : AddTrackPlanB(track, stream_ids));
   if (sender_or_error.ok()) {
-    UpdateNegotiationNeeded();
+    Observer()->OnRenegotiationNeeded();
     stats_->AddTrack(track);
   }
   return sender_or_error;
@@ -1469,7 +1460,7 @@
           "Couldn't find sender " + sender->id() + " to remove.");
     }
   }
-  UpdateNegotiationNeeded();
+  Observer()->OnRenegotiationNeeded();
   return RTCError::OK();
 }
 
@@ -1536,7 +1527,7 @@
     cricket::MediaType media_type,
     rtc::scoped_refptr<MediaStreamTrackInterface> track,
     const RtpTransceiverInit& init,
-    bool update_negotiation_needed) {
+    bool fire_callback) {
   RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
               media_type == cricket::MEDIA_TYPE_VIDEO));
   if (track) {
@@ -1625,8 +1616,8 @@
   auto transceiver = CreateAndAddTransceiver(sender, receiver);
   transceiver->internal()->set_direction(init.direction);
 
-  if (update_negotiation_needed) {
-    UpdateNegotiationNeeded();
+  if (fire_callback) {
+    Observer()->OnRenegotiationNeeded();
   }
 
   return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
@@ -1704,7 +1695,7 @@
 void PeerConnection::OnNegotiationNeeded() {
   RTC_DCHECK_RUN_ON(signaling_thread());
   RTC_DCHECK(!IsClosed());
-  UpdateNegotiationNeeded();
+  Observer()->OnRenegotiationNeeded();
 }
 
 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
@@ -1952,7 +1943,7 @@
   // Trigger the onRenegotiationNeeded event for every new RTP DataChannel, or
   // the first SCTP DataChannel.
   if (data_channel_type() == cricket::DCT_RTP || first_datachannel) {
-    UpdateNegotiationNeeded();
+    Observer()->OnRenegotiationNeeded();
   }
   NoteUsageEvent(UsageEvent::DATA_ADDED);
   return DataChannelProxy::Create(signaling_thread(), channel.get());
@@ -2054,8 +2045,7 @@
         << " transceiver since CreateOffer specified offer_to_receive=1";
     RtpTransceiverInit init;
     init.direction = RtpTransceiverDirection::kRecvOnly;
-    AddTransceiver(media_type, nullptr, init,
-                   /*update_negotiation_needed=*/false);
+    AddTransceiver(media_type, nullptr, init, /*fire_callback=*/false);
   }
 }
 
@@ -2199,14 +2189,6 @@
     // Make UMA notes about what was agreed to.
     ReportNegotiatedSdpSemantics(*local_description());
   }
-
-  bool was_negotiation_needed = is_negotiation_needed_;
-  UpdateNegotiationNeeded();
-  if (signaling_state() == kStable && was_negotiation_needed &&
-      is_negotiation_needed_) {
-    Observer()->OnRenegotiationNeeded();
-  }
-
   NoteUsageEvent(UsageEvent::SET_LOCAL_DESCRIPTION_CALLED);
 }
 
@@ -2564,13 +2546,6 @@
     ReportNegotiatedSdpSemantics(*remote_description());
   }
 
-  bool was_negotiation_needed = is_negotiation_needed_;
-  UpdateNegotiationNeeded();
-  if (signaling_state() == kStable && was_negotiation_needed &&
-      is_negotiation_needed_) {
-    Observer()->OnRenegotiationNeeded();
-  }
-
   observer->OnSetRemoteDescriptionComplete(RTCError::OK());
   NoteUsageEvent(UsageEvent::SET_REMOTE_DESCRIPTION_CALLED);
 }
@@ -4183,7 +4158,7 @@
     return;
   }
   AddAudioTrack(track, stream);
-  UpdateNegotiationNeeded();
+  Observer()->OnRenegotiationNeeded();
 }
 
 void PeerConnection::OnAudioTrackRemoved(AudioTrackInterface* track,
@@ -4192,7 +4167,7 @@
     return;
   }
   RemoveAudioTrack(track, stream);
-  UpdateNegotiationNeeded();
+  Observer()->OnRenegotiationNeeded();
 }
 
 void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track,
@@ -4201,7 +4176,7 @@
     return;
   }
   AddVideoTrack(track, stream);
-  UpdateNegotiationNeeded();
+  Observer()->OnRenegotiationNeeded();
 }
 
 void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track,
@@ -4210,7 +4185,7 @@
     return;
   }
   RemoveVideoTrack(track, stream);
-  UpdateNegotiationNeeded();
+  Observer()->OnRenegotiationNeeded();
 }
 
 void PeerConnection::PostSetSessionDescriptionSuccess(
@@ -7150,169 +7125,4 @@
                            nullptr);
 }
 
-void PeerConnection::UpdateNegotiationNeeded() {
-  RTC_DCHECK_RUN_ON(signaling_thread());
-  // If connection's [[IsClosed]] slot is true, abort these steps.
-  if (IsClosed())
-    return;
-
-  // If connection's signaling state is not "stable", abort these steps.
-  if (signaling_state() != kStable)
-    return;
-
-  // NOTE
-  // The negotiation-needed flag will be updated once the state transitions to
-  // "stable", as part of the steps for setting an RTCSessionDescription.
-
-  // If the result of checking if negotiation is needed is false, clear the
-  // negotiation-needed flag by setting connection's [[NegotiationNeeded]] slot
-  // to false, and abort these steps.
-  bool is_negotiation_needed = CheckIfNegotiationIsNeeded();
-  if (!is_negotiation_needed) {
-    is_negotiation_needed_ = false;
-    return;
-  }
-
-  // If connection's [[NegotiationNeeded]] slot is already true, abort these
-  // steps.
-  if (is_negotiation_needed_)
-    return;
-
-  // Set connection's [[NegotiationNeeded]] slot to true.
-  is_negotiation_needed_ = true;
-
-  // Queue a task that runs the following steps:
-  // If connection's [[IsClosed]] slot is true, abort these steps.
-  // If connection's [[NegotiationNeeded]] slot is false, abort these steps.
-  // Fire an event named negotiationneeded at connection.
-  Observer()->OnRenegotiationNeeded();
-}
-
-bool PeerConnection::CheckIfNegotiationIsNeeded() {
-  RTC_DCHECK_RUN_ON(signaling_thread());
-  // 1. If any implementation-specific negotiation is required, as described at
-  // the start of this section, return true.
-
-  // 2. Let description be connection.[[CurrentLocalDescription]].
-  const SessionDescriptionInterface* description = current_local_description();
-  if (!description)
-    return true;
-
-  // 3. If connection has created any RTCDataChannels, and no m= section in
-  // description has been negotiated yet for data, return true.
-  if (!sctp_data_channels_.empty()) {
-    if (!cricket::GetFirstDataContent(description->description()->contents()))
-      return true;
-  }
-
-  // 4. For each transceiver in connection's set of transceivers, perform the
-  // following checks:
-  for (const auto& transceiver : transceivers_) {
-    const ContentInfo* current_local_msection =
-        FindTransceiverMSection(transceiver.get(), description);
-
-    const ContentInfo* current_remote_msection = FindTransceiverMSection(
-        transceiver.get(), current_remote_description());
-
-    // 4.3 If transceiver is stopped and is associated with an m= section,
-    // but the associated m= section is not yet rejected in
-    // connection.[[CurrentLocalDescription]] or
-    // connection.[[CurrentRemoteDescription]], return true.
-    if (transceiver->stopped()) {
-      if (current_local_msection && !current_local_msection->rejected &&
-          ((current_remote_msection && !current_remote_msection->rejected) ||
-           !current_remote_msection)) {
-        return true;
-      }
-      continue;
-    }
-
-    // 4.1 If transceiver isn't stopped and isn't yet associated with an m=
-    // section in description, return true.
-    if (!current_local_msection)
-      return true;
-
-    const MediaContentDescription* current_local_media_description =
-        current_local_msection->media_description();
-    // 4.2 If transceiver isn't stopped and is associated with an m= section
-    // in description then perform the following checks:
-
-    // 4.2.1 If transceiver.[[Direction]] is "sendrecv" or "sendonly", and the
-    // associated m= section in description either doesn't contain a single
-    // "a=msid" line, or the number of MSIDs from the "a=msid" lines in this
-    // m= section, or the MSID values themselves, differ from what is in
-    // transceiver.sender.[[AssociatedMediaStreamIds]], return true.
-    if (RtpTransceiverDirectionHasSend(transceiver->direction())) {
-      if (current_local_media_description->streams().size() == 0)
-        return true;
-
-      std::vector<std::string> msection_msids;
-      for (const auto& stream : current_local_media_description->streams()) {
-        for (const std::string& msid : stream.stream_ids())
-          msection_msids.push_back(msid);
-      }
-
-      std::vector<std::string> transceiver_msids =
-          transceiver->sender()->stream_ids();
-      if (msection_msids.size() != transceiver_msids.size())
-        return true;
-
-      absl::c_sort(transceiver_msids);
-      absl::c_sort(msection_msids);
-      if (transceiver_msids != msection_msids)
-        return true;
-    }
-
-    // 4.2.2 If description is of type "offer", and the direction of the
-    // associated m= section in neither connection.[[CurrentLocalDescription]]
-    // nor connection.[[CurrentRemoteDescription]] matches
-    // transceiver.[[Direction]], return true.
-    if (description->GetType() == SdpType::kOffer) {
-      if (!current_remote_description())
-        return true;
-
-      if (!current_remote_msection)
-        return true;
-
-      RtpTransceiverDirection current_local_direction =
-          current_local_media_description->direction();
-      RtpTransceiverDirection current_remote_direction =
-          current_remote_msection->media_description()->direction();
-      if (transceiver->direction() != current_local_direction &&
-          transceiver->direction() !=
-              RtpTransceiverDirectionReversed(current_remote_direction)) {
-        return true;
-      }
-    }
-
-    // 4.2.3 If description is of type "answer", and the direction of the
-    // associated m= section in the description does not match
-    // transceiver.[[Direction]] intersected with the offered direction (as
-    // described in [JSEP] (section 5.3.1.)), return true.
-    if (description->GetType() == SdpType::kAnswer) {
-      if (!remote_description())
-        return true;
-
-      const ContentInfo* offered_remote_msection =
-          FindTransceiverMSection(transceiver.get(), remote_description());
-
-      RtpTransceiverDirection offered_direction =
-          offered_remote_msection
-              ? offered_remote_msection->media_description()->direction()
-              : RtpTransceiverDirection::kInactive;
-
-      if (current_local_media_description->direction() !=
-          (RtpTransceiverDirectionIntersection(
-              transceiver->direction(),
-              RtpTransceiverDirectionReversed(offered_direction)))) {
-        return true;
-      }
-    }
-  }
-
-  // If all the preceding checks were performed and true was not returned,
-  // nothing remains to be negotiated; return false.
-  return false;
-}
-
 }  // namespace webrtc
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index 2cf3662..c639a58 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -1086,9 +1086,6 @@
     return media_transport;
   }
 
-  void UpdateNegotiationNeeded();
-  bool CheckIfNegotiationIsNeeded();
-
   sigslot::signal1<DataChannel*> SignalDataChannelCreated_
       RTC_GUARDED_BY(signaling_thread());
 
@@ -1332,7 +1329,6 @@
   // channel manager and the session description factory.
   rtc::UniqueRandomIdGenerator ssrc_generator_
       RTC_GUARDED_BY(signaling_thread());
-  bool is_negotiation_needed_ RTC_GUARDED_BY(signaling_thread()) = false;
 };
 
 }  // namespace webrtc
diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc
index d73e45a..e69fc96 100644
--- a/pc/peer_connection_interface_unittest.cc
+++ b/pc/peer_connection_interface_unittest.cc
@@ -814,6 +814,8 @@
     auto sender_or_error =
         pc_->AddTrack(CreateVideoTrack(track_label), stream_ids);
     ASSERT_EQ(RTCErrorType::NONE, sender_or_error.error().type());
+    EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
+    observer_.renegotiation_needed_ = false;
   }
 
   void AddVideoStream(const std::string& label) {
@@ -821,6 +823,8 @@
         pc_factory_->CreateLocalMediaStream(label));
     stream->AddTrack(CreateVideoTrack(label + "v0"));
     ASSERT_TRUE(pc_->AddStream(stream));
+    EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
+    observer_.renegotiation_needed_ = false;
   }
 
   rtc::scoped_refptr<AudioTrackInterface> CreateAudioTrack(
@@ -833,6 +837,8 @@
     auto sender_or_error =
         pc_->AddTrack(CreateAudioTrack(track_label), stream_ids);
     ASSERT_EQ(RTCErrorType::NONE, sender_or_error.error().type());
+    EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
+    observer_.renegotiation_needed_ = false;
   }
 
   void AddAudioStream(const std::string& label) {
@@ -840,6 +846,8 @@
         pc_factory_->CreateLocalMediaStream(label));
     stream->AddTrack(CreateAudioTrack(label + "a0"));
     ASSERT_TRUE(pc_->AddStream(stream));
+    EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
+    observer_.renegotiation_needed_ = false;
   }
 
   void AddAudioVideoStream(const std::string& stream_id,
@@ -851,6 +859,8 @@
     stream->AddTrack(CreateAudioTrack(audio_track_label));
     stream->AddTrack(CreateVideoTrack(video_track_label));
     ASSERT_TRUE(pc_->AddStream(stream));
+    EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
+    observer_.renegotiation_needed_ = false;
   }
 
   rtc::scoped_refptr<RtpReceiverInterface> GetFirstReceiverOfType(
@@ -2194,12 +2204,9 @@
   EXPECT_TRUE(observer_.renegotiation_needed_);
   observer_.renegotiation_needed_ = false;
 
-  CreateOfferReceiveAnswer();
-
   rtc::scoped_refptr<DataChannelInterface> dc2 =
       pc_->CreateDataChannel("test2", NULL);
-  EXPECT_EQ(observer_.renegotiation_needed_,
-            GetParam() == SdpSemantics::kPlanB);
+  EXPECT_TRUE(observer_.renegotiation_needed_);
 }
 
 // This test that a data channel closes when a PeerConnection is deleted/closed.
@@ -3887,17 +3894,14 @@
   EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
   observer_.renegotiation_needed_ = false;
 
-  CreateOfferReceiveAnswer();
   stream->AddTrack(video_track);
   EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
   observer_.renegotiation_needed_ = false;
 
-  CreateOfferReceiveAnswer();
   stream->RemoveTrack(audio_track);
   EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
   observer_.renegotiation_needed_ = false;
 
-  CreateOfferReceiveAnswer();
   stream->RemoveTrack(video_track);
   EXPECT_TRUE_WAIT(observer_.renegotiation_needed_, kTimeout);
   observer_.renegotiation_needed_ = false;
diff --git a/pc/peer_connection_rtp_unittest.cc b/pc/peer_connection_rtp_unittest.cc
index 6925300..c03bab4 100644
--- a/pc/peer_connection_rtp_unittest.cc
+++ b/pc/peer_connection_rtp_unittest.cc
@@ -1135,14 +1135,11 @@
 TEST_F(PeerConnectionRtpTestUnifiedPlan,
        AddTrackChangesDirectionFromInactiveToSendOnly) {
   auto caller = CreatePeerConnection();
-  auto callee = CreatePeerConnection();
 
   RtpTransceiverInit init;
   init.direction = RtpTransceiverDirection::kInactive;
   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
-  EXPECT_TRUE(caller->observer()->negotiation_needed());
 
-  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
   caller->observer()->clear_negotiation_needed();
   ASSERT_TRUE(caller->AddAudioTrack("a"));
   EXPECT_TRUE(caller->observer()->negotiation_needed());
@@ -1155,14 +1152,11 @@
 TEST_F(PeerConnectionRtpTestUnifiedPlan,
        AddTrackChangesDirectionFromRecvOnlyToSendRecv) {
   auto caller = CreatePeerConnection();
-  auto callee = CreatePeerConnection();
 
   RtpTransceiverInit init;
   init.direction = RtpTransceiverDirection::kRecvOnly;
   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, init);
-  EXPECT_TRUE(caller->observer()->negotiation_needed());
 
-  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
   caller->observer()->clear_negotiation_needed();
   ASSERT_TRUE(caller->AddAudioTrack("a"));
   EXPECT_TRUE(caller->observer()->negotiation_needed());
@@ -1225,21 +1219,18 @@
 TEST_F(PeerConnectionRtpTestUnifiedPlan,
        RemoveTrackChangesDirectionFromSendRecvToRecvOnly) {
   auto caller = CreatePeerConnection();
-  auto callee = CreatePeerConnection();
 
   RtpTransceiverInit init;
   init.direction = RtpTransceiverDirection::kSendRecv;
   auto transceiver =
       caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
-  EXPECT_TRUE(caller->observer()->negotiation_needed());
 
-  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
   caller->observer()->clear_negotiation_needed();
-
   ASSERT_TRUE(caller->pc()->RemoveTrack(transceiver->sender()));
   EXPECT_TRUE(caller->observer()->negotiation_needed());
 
   EXPECT_EQ(RtpTransceiverDirection::kRecvOnly, transceiver->direction());
+  EXPECT_TRUE(caller->observer()->renegotiation_needed_);
 }
 
 // Test that calling RemoveTrack on a sender where the transceiver is configured
@@ -1247,17 +1238,13 @@
 TEST_F(PeerConnectionRtpTestUnifiedPlan,
        RemoveTrackChangesDirectionFromSendOnlyToInactive) {
   auto caller = CreatePeerConnection();
-  auto callee = CreatePeerConnection();
 
   RtpTransceiverInit init;
   init.direction = RtpTransceiverDirection::kSendOnly;
   auto transceiver =
       caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
-  EXPECT_TRUE(caller->observer()->negotiation_needed());
 
-  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
   caller->observer()->clear_negotiation_needed();
-
   ASSERT_TRUE(caller->pc()->RemoveTrack(transceiver->sender()));
   EXPECT_TRUE(caller->observer()->negotiation_needed());
 
@@ -1407,15 +1394,10 @@
 TEST_F(PeerConnectionRtpTestUnifiedPlan,
        RenegotiationNeededAfterTransceiverSetDirection) {
   auto caller = CreatePeerConnection();
-  auto callee = CreatePeerConnection();
-  EXPECT_FALSE(caller->observer()->negotiation_needed());
 
   auto transceiver = caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
-  EXPECT_TRUE(caller->observer()->negotiation_needed());
 
-  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
   caller->observer()->clear_negotiation_needed();
-
   transceiver->SetDirection(RtpTransceiverDirection::kInactive);
   EXPECT_TRUE(caller->observer()->negotiation_needed());
 }
@@ -1795,42 +1777,6 @@
   }
 }
 
-// This test exercises the code path that fires a NegotiationNeeded
-// notification when the stream IDs of the local description differ from
-// the ones in the transceiver. Since SetStreams() is not yet available
-// on RtpSenderInterface, adding a track is used to trigger the check for
-// the NegotiationNeeded notification.
-// TODO(https://crbug.com/webrtc/10129): Replace this test with a test that
-// checks that calling SetStreams() on a sender fires the notification once
-// the method becomes available in RtpSenderInterface.
-TEST_F(PeerConnectionRtpTestUnifiedPlan,
-       ChangeAssociatedStreamsTriggersRenegotiation) {
-  auto caller = CreatePeerConnection();
-  auto callee = CreatePeerConnection();
-
-  RtpTransceiverInit init;
-  init.direction = RtpTransceiverDirection::kSendRecv;
-  auto transceiver =
-      caller->AddTransceiver(caller->CreateAudioTrack("a"), init);
-  EXPECT_TRUE(caller->observer()->negotiation_needed());
-
-  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
-  caller->observer()->clear_negotiation_needed();
-
-  SessionDescriptionInterface* cld = const_cast<SessionDescriptionInterface*>(
-      caller->pc()->current_local_description());
-  ASSERT_EQ(cld->description()->contents().size(), 1u);
-
-  cricket::SessionDescription* description = cld->description();
-  cricket::ContentInfo& content_info = description->contents()[0];
-  ASSERT_EQ(content_info.media_description()->mutable_streams().size(), 1u);
-  content_info.media_description()->mutable_streams()[0].set_stream_ids(
-      {"stream3", "stream4", "stream5"});
-
-  ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("a2")));
-  EXPECT_TRUE(caller->observer()->negotiation_needed());
-}
-
 INSTANTIATE_TEST_SUITE_P(PeerConnectionRtpTest,
                          PeerConnectionRtpTest,
                          Values(SdpSemantics::kPlanB,
diff --git a/pc/rtp_media_utils.cc b/pc/rtp_media_utils.cc
index 6e8be58..f4a6120 100644
--- a/pc/rtp_media_utils.cc
+++ b/pc/rtp_media_utils.cc
@@ -81,14 +81,4 @@
   return "";
 }
 
-RtpTransceiverDirection RtpTransceiverDirectionIntersection(
-    RtpTransceiverDirection lhs,
-    RtpTransceiverDirection rhs) {
-  return RtpTransceiverDirectionFromSendRecv(
-      RtpTransceiverDirectionHasSend(lhs) &&
-          RtpTransceiverDirectionHasSend(rhs),
-      RtpTransceiverDirectionHasRecv(lhs) &&
-          RtpTransceiverDirectionHasRecv(rhs));
-}
-
 }  // namespace webrtc
diff --git a/pc/rtp_media_utils.h b/pc/rtp_media_utils.h
index f556fe39..3ff40c9 100644
--- a/pc/rtp_media_utils.h
+++ b/pc/rtp_media_utils.h
@@ -44,11 +44,6 @@
 // Returns an unspecified string representation of the given direction.
 const char* RtpTransceiverDirectionToString(RtpTransceiverDirection direction);
 
-// Returns the intersection of the directions of two transceivers.
-RtpTransceiverDirection RtpTransceiverDirectionIntersection(
-    RtpTransceiverDirection lhs,
-    RtpTransceiverDirection rhs);
-
 #ifdef UNIT_TEST
 inline std::ostream& operator<<(  // no-presubmit-check TODO(webrtc:8982)
     std::ostream& os,             // no-presubmit-check TODO(webrtc:8982)
diff --git a/sdk/android/instrumentationtests/src/org/webrtc/PeerConnectionTest.java b/sdk/android/instrumentationtests/src/org/webrtc/PeerConnectionTest.java
index cedb356..bf23d19 100644
--- a/sdk/android/instrumentationtests/src/org/webrtc/PeerConnectionTest.java
+++ b/sdk/android/instrumentationtests/src/org/webrtc/PeerConnectionTest.java
@@ -1132,10 +1132,8 @@
     System.gc();
   }
 
-  // TODO(https://bugs.webrtc.org/10526): Fix and re-enable this test.
   @Test
   @MediumTest
-  @DisabledTest
   public void testDataChannelOnlySession() throws Exception {
     // Allow loopback interfaces too since our Android devices often don't
     // have those.
@@ -1293,10 +1291,8 @@
     System.gc();
   }
 
-  // TODO(https://bugs.webrtc.org/10526): Fix and re-enable this test.
   @Test
   @MediumTest
-  @DisabledTest
   public void testTrackRemovalAndAddition() throws Exception {
     // Allow loopback interfaces too since our Android devices often don't
     // have those.