Add an option to avoid Java video track release when peer connection is closed.

Currently disposing Java peer connection object will result in auto
release of media streams and media tracks added to peer connection.
Add an option to allow application to own video track so it can be
kept after peer connection is destroyed.

R=jiayl@webrtc.org, wzh@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#9946}
diff --git a/talk/app/webrtc/java/src/org/webrtc/MediaStream.java b/talk/app/webrtc/java/src/org/webrtc/MediaStream.java
index aa5b3e0..be00f13 100644
--- a/talk/app/webrtc/java/src/org/webrtc/MediaStream.java
+++ b/talk/app/webrtc/java/src/org/webrtc/MediaStream.java
@@ -33,12 +33,14 @@
 public class MediaStream {
   public final LinkedList<AudioTrack> audioTracks;
   public final LinkedList<VideoTrack> videoTracks;
+  public final LinkedList<VideoTrack> preservedVideoTracks;
   // Package-protected for PeerConnection.
   final long nativeStream;
 
   public MediaStream(long nativeStream) {
     audioTracks = new LinkedList<AudioTrack>();
     videoTracks = new LinkedList<VideoTrack>();
+    preservedVideoTracks = new LinkedList<VideoTrack>();
     this.nativeStream = nativeStream;
   }
 
@@ -58,6 +60,17 @@
     return false;
   }
 
+  // Tracks added in addTrack() call will be auto released once MediaStream.dispose()
+  // is called. If video track need to be preserved after MediaStream is destroyed it
+  // should be added to MediaStream using addPreservedTrack() call.
+  public boolean addPreservedTrack(VideoTrack track) {
+    if (nativeAddVideoTrack(nativeStream, track.nativeTrack)) {
+      preservedVideoTracks.add(track);
+      return true;
+    }
+    return false;
+  }
+
   public boolean removeTrack(AudioTrack track) {
     if (nativeRemoveAudioTrack(nativeStream, track.nativeTrack)) {
       audioTracks.remove(track);
@@ -69,12 +82,14 @@
   public boolean removeTrack(VideoTrack track) {
     if (nativeRemoveVideoTrack(nativeStream, track.nativeTrack)) {
       videoTracks.remove(track);
+      preservedVideoTracks.remove(track);
       return true;
     }
     return false;
   }
 
   public void dispose() {
+    // Remove and release previously added audio and video tracks.
     while (!audioTracks.isEmpty()) {
       AudioTrack track = audioTracks.getFirst();
       removeTrack(track);
@@ -85,6 +100,10 @@
       removeTrack(track);
       track.dispose();
     }
+    // Remove, but do not release preserved video tracks.
+    while (!preservedVideoTracks.isEmpty()) {
+      removeTrack(preservedVideoTracks.getFirst());
+    }
     free(nativeStream);
   }