Propagate MediaStreamSource state to video tracks the same way as audio.
Also removes unused track states kLive and kFailed.
Since this also required a Video source to exist in all unit tests that create a track, a FakeVideoTrackSource is added and used in tests.

BUG=webrtc:5426

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

Cr-Commit-Position: refs/heads/master@{#12098}
diff --git a/webrtc/api/audiotrack.cc b/webrtc/api/audiotrack.cc
index 5e92686..c2c9557 100644
--- a/webrtc/api/audiotrack.cc
+++ b/webrtc/api/audiotrack.cc
@@ -65,27 +65,11 @@
 
 void AudioTrack::OnChanged() {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
-  if (state() == kFailed)
-    return;  // We can't recover from this state (do we ever set it?).
-
-  TrackState new_state = kInitializing;
-
-  // |audio_source_| must be non-null if we ever get here.
-  switch (audio_source_->state()) {
-    case MediaSourceInterface::kLive:
-    case MediaSourceInterface::kMuted:
-      new_state = kLive;
-      break;
-    case MediaSourceInterface::kEnded:
-      new_state = kEnded;
-      break;
-    case MediaSourceInterface::kInitializing:
-    default:
-      // use kInitializing.
-      break;
+  if (audio_source_->state() == MediaSourceInterface::kEnded) {
+    set_state(kEnded);
+  } else {
+    set_state(kLive);
   }
-
-  set_state(new_state);
 }
 
 }  // namespace webrtc
diff --git a/webrtc/api/java/src/org/webrtc/MediaStreamTrack.java b/webrtc/api/java/src/org/webrtc/MediaStreamTrack.java
index ddc2a98..a0063fb 100644
--- a/webrtc/api/java/src/org/webrtc/MediaStreamTrack.java
+++ b/webrtc/api/java/src/org/webrtc/MediaStreamTrack.java
@@ -13,9 +13,7 @@
 /** Java wrapper for a C++ MediaStreamTrackInterface. */
 public class MediaStreamTrack {
   /** Tracks MediaStreamTrackInterface.TrackState */
-  public enum State {
-    INITIALIZING, LIVE, ENDED, FAILED
-  }
+  public enum State { LIVE, ENDED }
 
   final long nativeTrack;
 
diff --git a/webrtc/api/mediastream_unittest.cc b/webrtc/api/mediastream_unittest.cc
index f017466..7d9c60d 100644
--- a/webrtc/api/mediastream_unittest.cc
+++ b/webrtc/api/mediastream_unittest.cc
@@ -60,12 +60,12 @@
     video_track_ =
         VideoTrack::Create(kVideoTrackId, FakeVideoTrackSource::Create());
     ASSERT_TRUE(video_track_.get() != NULL);
-    EXPECT_EQ(MediaStreamTrackInterface::kInitializing, video_track_->state());
+    EXPECT_EQ(MediaStreamTrackInterface::kLive, video_track_->state());
 
     audio_track_ = AudioTrack::Create(kAudioTrackId, NULL);
 
     ASSERT_TRUE(audio_track_.get() != NULL);
-    EXPECT_EQ(MediaStreamTrackInterface::kInitializing, audio_track_->state());
+    EXPECT_EQ(MediaStreamTrackInterface::kLive, audio_track_->state());
 
     EXPECT_TRUE(stream_->AddTrack(video_track_));
     EXPECT_FALSE(stream_->AddTrack(video_track_));
@@ -83,8 +83,8 @@
 
     EXPECT_CALL(observer, OnChanged())
         .Times(Exactly(1));
-    track->set_state(MediaStreamTrackInterface::kLive);
-    EXPECT_EQ(MediaStreamTrackInterface::kLive, track->state());
+    track->set_state(MediaStreamTrackInterface::kEnded);
+    EXPECT_EQ(MediaStreamTrackInterface::kEnded, track->state());
   }
 
   scoped_refptr<MediaStreamInterface> stream_;
diff --git a/webrtc/api/mediastreaminterface.h b/webrtc/api/mediastreaminterface.h
index 69a50c9..a1ab675 100644
--- a/webrtc/api/mediastreaminterface.h
+++ b/webrtc/api/mediastreaminterface.h
@@ -80,10 +80,8 @@
                                   public NotifierInterface {
  public:
   enum TrackState {
-    kInitializing,  // Track is beeing negotiated.
-    kLive = 1,  // Track alive
-    kEnded = 2,  // Track have ended
-    kFailed = 3,  // Track negotiation failed.
+    kLive,
+    kEnded,
   };
 
   static const char kAudioKind[];
diff --git a/webrtc/api/mediastreamtrack.h b/webrtc/api/mediastreamtrack.h
index dcac581..e6f02e5 100644
--- a/webrtc/api/mediastreamtrack.h
+++ b/webrtc/api/mediastreamtrack.h
@@ -48,10 +48,7 @@
 
  protected:
   explicit MediaStreamTrack(const std::string& id)
-      : enabled_(true),
-        id_(id),
-        state_(MediaStreamTrackInterface::kInitializing) {
-  }
+      : enabled_(true), id_(id), state_(MediaStreamTrackInterface::kLive) {}
 
  private:
   bool enabled_;
diff --git a/webrtc/api/objc/RTCMediaStreamTrack.h b/webrtc/api/objc/RTCMediaStreamTrack.h
index 7883843..b8576bd 100644
--- a/webrtc/api/objc/RTCMediaStreamTrack.h
+++ b/webrtc/api/objc/RTCMediaStreamTrack.h
@@ -11,14 +11,11 @@
 #import <Foundation/Foundation.h>
 
 /**
- * Represents the state of the track. This exposes the same states in C++,
- * which include two more states than are in the W3C spec.
+ * Represents the state of the track. This exposes the same states in C++.
  */
 typedef NS_ENUM(NSInteger, RTCMediaStreamTrackState) {
-  RTCMediaStreamTrackStateInitializing,
   RTCMediaStreamTrackStateLive,
-  RTCMediaStreamTrackStateEnded,
-  RTCMediaStreamTrackStateFailed,
+  RTCMediaStreamTrackStateEnded
 };
 
 NS_ASSUME_NONNULL_BEGIN
diff --git a/webrtc/api/objc/RTCMediaStreamTrack.mm b/webrtc/api/objc/RTCMediaStreamTrack.mm
index 260c89d..25979b3 100644
--- a/webrtc/api/objc/RTCMediaStreamTrack.mm
+++ b/webrtc/api/objc/RTCMediaStreamTrack.mm
@@ -67,41 +67,29 @@
 + (webrtc::MediaStreamTrackInterface::TrackState)nativeTrackStateForState:
     (RTCMediaStreamTrackState)state {
   switch (state) {
-    case RTCMediaStreamTrackStateInitializing:
-      return webrtc::MediaStreamTrackInterface::kInitializing;
     case RTCMediaStreamTrackStateLive:
       return webrtc::MediaStreamTrackInterface::kLive;
     case RTCMediaStreamTrackStateEnded:
       return webrtc::MediaStreamTrackInterface::kEnded;
-    case RTCMediaStreamTrackStateFailed:
-      return webrtc::MediaStreamTrackInterface::kFailed;
   }
 }
 
 + (RTCMediaStreamTrackState)trackStateForNativeState:
     (webrtc::MediaStreamTrackInterface::TrackState)nativeState {
   switch (nativeState) {
-    case webrtc::MediaStreamTrackInterface::kInitializing:
-      return RTCMediaStreamTrackStateInitializing;
     case webrtc::MediaStreamTrackInterface::kLive:
       return RTCMediaStreamTrackStateLive;
     case webrtc::MediaStreamTrackInterface::kEnded:
       return RTCMediaStreamTrackStateEnded;
-    case webrtc::MediaStreamTrackInterface::kFailed:
-      return RTCMediaStreamTrackStateFailed;
   }
 }
 
 + (NSString *)stringForState:(RTCMediaStreamTrackState)state {
   switch (state) {
-    case RTCMediaStreamTrackStateInitializing:
-      return @"Initializing";
     case RTCMediaStreamTrackStateLive:
       return @"Live";
     case RTCMediaStreamTrackStateEnded:
       return @"Ended";
-    case RTCMediaStreamTrackStateFailed:
-      return @"Failed";
   }
 }
 
diff --git a/webrtc/api/rtpreceiver.cc b/webrtc/api/rtpreceiver.cc
index 1590612..f8b5057 100644
--- a/webrtc/api/rtpreceiver.cc
+++ b/webrtc/api/rtpreceiver.cc
@@ -81,10 +81,6 @@
           rtc::Thread::Current(),
           VideoTrack::Create(track_id, source_.get()))) {
   source_->SetState(MediaSourceInterface::kLive);
-  // TODO(perkj): It should be enough to set the source state. All tracks
-  // belonging to the same source should get its state from the source.
-  // I.e. if a track has been cloned from a remote source.
-  track_->set_state(webrtc::MediaStreamTrackInterface::kLive);
   provider_->SetVideoPlayout(ssrc_, true, &broadcaster_);
   stream->AddTrack(track_);
 }
@@ -102,9 +98,6 @@
   }
   source_->SetState(MediaSourceInterface::kEnded);
   source_->OnSourceDestroyed();
-  // TODO(perkj): It should be enough to set the source state. All tracks
-  // belonging to the same source should get its state from the source.
-  track_->set_state(MediaStreamTrackInterface::kEnded);
   provider_->SetVideoPlayout(ssrc_, false, nullptr);
   provider_ = nullptr;
 }
diff --git a/webrtc/api/videotrack.cc b/webrtc/api/videotrack.cc
index 54c3cce..bd38025 100644
--- a/webrtc/api/videotrack.cc
+++ b/webrtc/api/videotrack.cc
@@ -20,9 +20,11 @@
                        VideoTrackSourceInterface* video_source)
     : MediaStreamTrack<VideoTrackInterface>(label),
       video_source_(video_source) {
+  video_source_->RegisterObserver(this);
 }
 
 VideoTrack::~VideoTrack() {
+  video_source_->UnregisterObserver(this);
 }
 
 std::string VideoTrack::kind() const {
@@ -56,6 +58,15 @@
   return MediaStreamTrack<VideoTrackInterface>::set_enabled(enable);
 }
 
+void VideoTrack::OnChanged() {
+  RTC_DCHECK(thread_checker_.CalledOnValidThread());
+  if (video_source_->state() == MediaSourceInterface::kEnded) {
+    set_state(kEnded);
+  } else {
+    set_state(kLive);
+  }
+}
+
 rtc::scoped_refptr<VideoTrack> VideoTrack::Create(
     const std::string& id,
     VideoTrackSourceInterface* source) {
diff --git a/webrtc/api/videotrack.h b/webrtc/api/videotrack.h
index 36b03b8..3835d2c 100644
--- a/webrtc/api/videotrack.h
+++ b/webrtc/api/videotrack.h
@@ -22,7 +22,8 @@
 namespace webrtc {
 
 class VideoTrack : public MediaStreamTrack<VideoTrackInterface>,
-                   public rtc::VideoSourceBase {
+                   public rtc::VideoSourceBase,
+                   public ObserverInterface {
  public:
   static rtc::scoped_refptr<VideoTrack> Create(
       const std::string& label,
@@ -43,6 +44,9 @@
   ~VideoTrack();
 
  private:
+  // Implements ObserverInterface. Observes |video_source_| state.
+  void OnChanged() override;
+
   rtc::ThreadChecker thread_checker_;
   rtc::scoped_refptr<VideoTrackSourceInterface> video_source_;
 };
diff --git a/webrtc/api/videotrack_unittest.cc b/webrtc/api/videotrack_unittest.cc
index 6dac507..0df8679 100644
--- a/webrtc/api/videotrack_unittest.cc
+++ b/webrtc/api/videotrack_unittest.cc
@@ -21,19 +21,19 @@
 
 using webrtc::FakeVideoTrackRenderer;
 using webrtc::FakeVideoTrackRendererOld;
+using webrtc::MediaSourceInterface;
+using webrtc::MediaStreamTrackInterface;
 using webrtc::VideoTrackSource;
 using webrtc::VideoTrack;
 using webrtc::VideoTrackInterface;
 
-
 class VideoTrackTest : public testing::Test {
  public:
   VideoTrackTest() {
     static const char kVideoTrackId[] = "track_id";
-    video_track_ = VideoTrack::Create(
-        kVideoTrackId,
-        new rtc::RefCountedObject<VideoTrackSource>(
-            &capturer_, rtc::Thread::Current(), true /* remote */));
+    video_track_source_ = new rtc::RefCountedObject<VideoTrackSource>(
+        &capturer_, rtc::Thread::Current(), true /* remote */);
+    video_track_ = VideoTrack::Create(kVideoTrackId, video_track_source_);
     capturer_.Start(
         cricket::VideoFormat(640, 480, cricket::VideoFormat::FpsToInterval(30),
                              cricket::FOURCC_I420));
@@ -41,9 +41,17 @@
 
  protected:
   cricket::FakeVideoCapturer capturer_;
+  rtc::scoped_refptr<VideoTrackSource> video_track_source_;
   rtc::scoped_refptr<VideoTrackInterface> video_track_;
 };
 
+// Test changing the source state also changes the track state.
+TEST_F(VideoTrackTest, SourceStateChangeTrackState) {
+  EXPECT_EQ(MediaStreamTrackInterface::kLive, video_track_->state());
+  video_track_source_->SetState(MediaSourceInterface::kEnded);
+  EXPECT_EQ(MediaStreamTrackInterface::kEnded, video_track_->state());
+}
+
 // Test adding renderers to a video track and render to them by providing
 // frames to the source.
 TEST_F(VideoTrackTest, RenderVideo) {