Implement OnRemoveTrack and OnRemoveStream for Unified Plan

Also parameterizes the PeerConnection RTP unit tests to test
Unified Plan also.

Bug: webrtc:8587
Change-Id: I7661d9f2ec4b3bce0d2e2979035fa02225e3f118
Reviewed-on: https://webrtc-review.googlesource.com/73284
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23157}
diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc
index 54de56c..552bd2f 100644
--- a/pc/peerconnection.cc
+++ b/pc/peerconnection.cc
@@ -2360,8 +2360,11 @@
 
   if (IsUnifiedPlan()) {
     std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
-        receiving_transceivers;
+        now_receiving_transceivers;
+    std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
+        no_longer_receiving_transceivers;
     std::vector<rtc::scoped_refptr<MediaStreamInterface>> added_streams;
+    std::vector<rtc::scoped_refptr<MediaStreamInterface>> removed_streams;
     for (auto transceiver : transceivers_) {
       const ContentInfo* content =
           FindMediaSectionForTransceiver(transceiver, remote_description());
@@ -2400,8 +2403,9 @@
           }
           media_streams.push_back(stream);
         }
+        // This will add the remote track to the streams.
         transceiver->internal()->receiver_internal()->SetStreams(media_streams);
-        receiving_transceivers.push_back(transceiver);
+        now_receiving_transceivers.push_back(transceiver);
       }
       // If direction is sendonly or inactive, and transceiver's current
       // direction is neither sendonly nor inactive, process the removal of a
@@ -2411,7 +2415,19 @@
            RtpTransceiverDirectionHasRecv(*transceiver->current_direction()))) {
         RTC_LOG(LS_INFO) << "Processing the removal of a track for MID="
                          << content->name;
+        std::vector<rtc::scoped_refptr<MediaStreamInterface>> media_streams =
+            transceiver->internal()->receiver_internal()->streams();
+        // This will remove the remote track from the streams.
         transceiver->internal()->receiver_internal()->SetStreams({});
+        no_longer_receiving_transceivers.push_back(transceiver);
+        // Remove any streams that no longer have tracks.
+        for (auto stream : media_streams) {
+          if (stream->GetAudioTracks().empty() &&
+              stream->GetVideoTracks().empty()) {
+            remote_streams_->RemoveStream(stream);
+            removed_streams.push_back(stream);
+          }
+        }
       }
       if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
         transceiver->internal()->set_current_direction(local_direction);
@@ -2433,7 +2449,7 @@
       }
     }
     // Once all processing has finished, fire off callbacks.
-    for (auto transceiver : receiving_transceivers) {
+    for (auto transceiver : now_receiving_transceivers) {
       stats_->AddTrack(transceiver->receiver()->track());
       observer_->OnTrack(transceiver);
       observer_->OnAddTrack(transceiver->receiver(),
@@ -2442,6 +2458,12 @@
     for (auto stream : added_streams) {
       observer_->OnAddStream(stream);
     }
+    for (auto transceiver : no_longer_receiving_transceivers) {
+      observer_->OnRemoveTrack(transceiver->receiver());
+    }
+    for (auto stream : removed_streams) {
+      observer_->OnRemoveStream(stream);
+    }
   }
 
   const cricket::ContentInfo* audio_content =