Adding a MediaStream parameter to createSender.

This will allow an app to create senders with the same stream id,
without SDP munging.

Review URL: https://codereview.webrtc.org/1538673002

Cr-Commit-Position: refs/heads/master@{#11092}
diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc
index b16f945..c31859d 100644
--- a/talk/app/webrtc/java/jni/peerconnection_jni.cc
+++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc
@@ -1792,14 +1792,15 @@
 }
 
 JOW(jobject, PeerConnection_nativeCreateSender)(
-    JNIEnv* jni, jobject j_pc, jstring j_kind) {
+    JNIEnv* jni, jobject j_pc, jstring j_kind, jstring j_stream_id) {
   jclass j_rtp_sender_class = FindClass(jni, "org/webrtc/RtpSender");
   jmethodID j_rtp_sender_ctor =
       GetMethodID(jni, j_rtp_sender_class, "<init>", "(J)V");
 
   std::string kind = JavaToStdString(jni, j_kind);
+  std::string stream_id = JavaToStdString(jni, j_stream_id);
   rtc::scoped_refptr<RtpSenderInterface> sender =
-      ExtractNativePC(jni, j_pc)->CreateSender(kind);
+      ExtractNativePC(jni, j_pc)->CreateSender(kind, stream_id);
   if (!sender.get()) {
     return nullptr;
   }
diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
index 5f037a1..36cd075 100644
--- a/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
+++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnection.java
@@ -224,8 +224,8 @@
     localStreams.remove(stream);
   }
 
-  public RtpSender createSender(String kind) {
-    RtpSender new_sender = nativeCreateSender(kind);
+  public RtpSender createSender(String kind, String stream_id) {
+    RtpSender new_sender = nativeCreateSender(kind, stream_id);
     if (new_sender != null) {
       senders.add(new_sender);
     }
@@ -297,7 +297,7 @@
   private native boolean nativeGetStats(
       StatsObserver observer, long nativeTrack);
 
-  private native RtpSender nativeCreateSender(String kind);
+  private native RtpSender nativeCreateSender(String kind, String stream_id);
 
   private native List<RtpSender> nativeGetSenders();
 
diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc
index 85e03f9..617eb15 100644
--- a/talk/app/webrtc/peerconnection.cc
+++ b/talk/app/webrtc/peerconnection.cc
@@ -813,7 +813,8 @@
 }
 
 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
-    const std::string& kind) {
+    const std::string& kind,
+    const std::string& stream_id) {
   TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
   RtpSenderInterface* new_sender;
   if (kind == MediaStreamTrackInterface::kAudioKind) {
@@ -824,6 +825,9 @@
     LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
     return rtc::scoped_refptr<RtpSenderInterface>();
   }
+  if (!stream_id.empty()) {
+    new_sender->set_stream_id(stream_id);
+  }
   senders_.push_back(new_sender);
   return RtpSenderProxy::Create(signaling_thread(), new_sender);
 }
diff --git a/talk/app/webrtc/peerconnection.h b/talk/app/webrtc/peerconnection.h
index f6c4fc3..ab3fdcc 100644
--- a/talk/app/webrtc/peerconnection.h
+++ b/talk/app/webrtc/peerconnection.h
@@ -103,7 +103,8 @@
       AudioTrackInterface* track) override;
 
   rtc::scoped_refptr<RtpSenderInterface> CreateSender(
-      const std::string& kind) override;
+      const std::string& kind,
+      const std::string& stream_id) override;
 
   std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
       const override;
diff --git a/talk/app/webrtc/peerconnection_unittest.cc b/talk/app/webrtc/peerconnection_unittest.cc
index a127869..44c7e7f 100644
--- a/talk/app/webrtc/peerconnection_unittest.cc
+++ b/talk/app/webrtc/peerconnection_unittest.cc
@@ -1817,8 +1817,10 @@
 // received end-to-end.
 TEST_F(P2PTestConductor, EarlyWarmupTest) {
   ASSERT_TRUE(CreateTestClients());
-  auto audio_sender = initializing_client()->pc()->CreateSender("audio");
-  auto video_sender = initializing_client()->pc()->CreateSender("video");
+  auto audio_sender =
+      initializing_client()->pc()->CreateSender("audio", "stream_id");
+  auto video_sender =
+      initializing_client()->pc()->CreateSender("video", "stream_id");
   initializing_client()->Negotiate();
   // Wait for ICE connection to complete, without any tracks.
   // Note that the receiving client WILL (in HandleIncomingOffer) create
diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h
index 799ca15..4648176 100644
--- a/talk/app/webrtc/peerconnectioninterface.h
+++ b/talk/app/webrtc/peerconnectioninterface.h
@@ -338,8 +338,11 @@
 
   // TODO(deadbeef): Make these pure virtual once all subclasses implement them.
   // |kind| must be "audio" or "video".
+  // |stream_id| is used to populate the msid attribute; if empty, one will
+  // be generated automatically.
   virtual rtc::scoped_refptr<RtpSenderInterface> CreateSender(
-      const std::string& kind) {
+      const std::string& kind,
+      const std::string& stream_id) {
     return rtc::scoped_refptr<RtpSenderInterface>();
   }
 
diff --git a/talk/app/webrtc/peerconnectioninterface_unittest.cc b/talk/app/webrtc/peerconnectioninterface_unittest.cc
index 930f538..098f8ae 100644
--- a/talk/app/webrtc/peerconnectioninterface_unittest.cc
+++ b/talk/app/webrtc/peerconnectioninterface_unittest.cc
@@ -1198,6 +1198,22 @@
   EXPECT_TRUE(video_desc == nullptr);
 }
 
+// Test creating a sender with a stream ID, and ensure the ID is populated
+// in the offer.
+TEST_F(PeerConnectionInterfaceTest, CreateSenderWithStream) {
+  CreatePeerConnection();
+  pc_->CreateSender("video", kStreamLabel1);
+
+  scoped_ptr<SessionDescriptionInterface> offer;
+  ASSERT_TRUE(DoCreateOffer(offer.use(), nullptr));
+
+  const cricket::MediaContentDescription* video_desc =
+      cricket::GetFirstVideoContentDescription(offer->description());
+  ASSERT_TRUE(video_desc != nullptr);
+  ASSERT_EQ(1u, video_desc->streams().size());
+  EXPECT_EQ(kStreamLabel1, video_desc->streams()[0].sync_label);
+}
+
 // Test that we can specify a certain track that we want statistics about.
 TEST_F(PeerConnectionInterfaceTest, GetStatsForSpecificTrack) {
   InitiateCall();
diff --git a/talk/app/webrtc/peerconnectionproxy.h b/talk/app/webrtc/peerconnectionproxy.h
index 9b446c0..3c983d7 100644
--- a/talk/app/webrtc/peerconnectionproxy.h
+++ b/talk/app/webrtc/peerconnectionproxy.h
@@ -43,8 +43,9 @@
   PROXY_METHOD1(void, RemoveStream, MediaStreamInterface*)
   PROXY_METHOD1(rtc::scoped_refptr<DtmfSenderInterface>,
                 CreateDtmfSender, AudioTrackInterface*)
-  PROXY_METHOD1(rtc::scoped_refptr<RtpSenderInterface>,
+  PROXY_METHOD2(rtc::scoped_refptr<RtpSenderInterface>,
                 CreateSender,
+                const std::string&,
                 const std::string&)
   PROXY_CONSTMETHOD0(std::vector<rtc::scoped_refptr<RtpSenderInterface>>,
                      GetSenders)