// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/media/media_stream_impl.h"

#include <utility>

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/renderer/media/media_stream_audio_renderer.h"
#include "content/renderer/media/media_stream_dependency_factory.h"
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/media_stream_extra_data.h"
#include "content/renderer/media/media_stream_source_extra_data.h"
#include "content/renderer/media/rtc_video_renderer.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
#include "content/renderer/media/webrtc_audio_renderer.h"
#include "content/renderer/media/webrtc_local_audio_renderer.h"
#include "content/renderer/media/webrtc_uma_histograms.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebMediaStreamRegistry.h"

namespace content {
namespace {

std::string GetStreamConstraint(
    const WebKit::WebMediaConstraints& constraints, const std::string& key,
    bool is_mandatory) {
  if (constraints.isNull())
    return std::string();

  WebKit::WebString value;
  if (is_mandatory) {
    constraints.getMandatoryConstraintValue(UTF8ToUTF16(key), value);
  } else {
    constraints.getOptionalConstraintValue(UTF8ToUTF16(key), value);
  }
  return UTF16ToUTF8(value);
}

void UpdateRequestOptions(
    const WebKit::WebUserMediaRequest& user_media_request,
    StreamOptions* options) {
  if (options->audio_type != content::MEDIA_NO_SERVICE) {
    std::string audio_stream_source = GetStreamConstraint(
        user_media_request.audioConstraints(), kMediaStreamSource, true);
    if (audio_stream_source == kMediaStreamSourceTab) {
      options->audio_type = content::MEDIA_TAB_AUDIO_CAPTURE;
      options->audio_device_id = GetStreamConstraint(
          user_media_request.audioConstraints(),
          kMediaStreamSourceId, true);
    } else if (audio_stream_source == kMediaStreamSourceSystem) {
      options->audio_type = content::MEDIA_SYSTEM_AUDIO_CAPTURE;
    }
  }

  if (options->video_type != content::MEDIA_NO_SERVICE) {
    std::string video_stream_source = GetStreamConstraint(
        user_media_request.videoConstraints(), kMediaStreamSource, true);
    if (video_stream_source == kMediaStreamSourceTab) {
      options->video_type = content::MEDIA_TAB_VIDEO_CAPTURE;
      options->video_device_id = GetStreamConstraint(
          user_media_request.videoConstraints(),
          kMediaStreamSourceId, true);
    } else if (video_stream_source == kMediaStreamSourceScreen) {
      options->video_type = content::MEDIA_SCREEN_VIDEO_CAPTURE;
    }
  }
}

static int g_next_request_id  = 0;

// Creates a WebKit representation of a stream sources based on
// |devices| from the MediaStreamDispatcher.
void CreateWebKitSourceVector(
    const std::string& label,
    const StreamDeviceInfoArray& devices,
    WebKit::WebMediaStreamSource::Type type,
    WebKit::WebVector<WebKit::WebMediaStreamSource>& webkit_sources) {
  CHECK_EQ(devices.size(), webkit_sources.size());
  for (size_t i = 0; i < devices.size(); ++i) {
    const char* track_type =
        (type == WebKit::WebMediaStreamSource::TypeAudio) ? "a" : "v";
    std::string source_id = base::StringPrintf("%s%s%u", label.c_str(),
                                               track_type,
                                               static_cast<unsigned int>(i));
    webkit_sources[i].initialize(
          UTF8ToUTF16(source_id),
          type,
          UTF8ToUTF16(devices[i].device.name));
    webkit_sources[i].setExtraData(
        new content::MediaStreamSourceExtraData(devices[i], webkit_sources[i]));
    webkit_sources[i].setDeviceId(UTF8ToUTF16(
        base::IntToString(devices[i].session_id)));
  }
}

webrtc::MediaStreamInterface* GetNativeMediaStream(
    const WebKit::WebMediaStream& web_stream) {
  content::MediaStreamExtraData* extra_data =
      static_cast<content::MediaStreamExtraData*>(web_stream.extraData());
  if (!extra_data)
    return NULL;
  return extra_data->stream().get();
}

}  // namespace

MediaStreamImpl::MediaStreamImpl(
    RenderView* render_view,
    MediaStreamDispatcher* media_stream_dispatcher,
    MediaStreamDependencyFactory* dependency_factory)
    : RenderViewObserver(render_view),
      dependency_factory_(dependency_factory),
      media_stream_dispatcher_(media_stream_dispatcher) {
}

MediaStreamImpl::~MediaStreamImpl() {
}

void MediaStreamImpl::OnLocalMediaStreamStop(
    const std::string& label) {
  DVLOG(1) << "MediaStreamImpl::OnLocalMediaStreamStop(" << label << ")";

  UserMediaRequestInfo* user_media_request = FindUserMediaRequestInfo(label);
  if (user_media_request) {
    StopLocalAudioTrack(user_media_request->web_stream);
    media_stream_dispatcher_->StopStream(label);
    DeleteUserMediaRequestInfo(user_media_request);
  } else {
    DVLOG(1) << "MediaStreamImpl::OnLocalMediaStreamStop: the stream has "
             << "already been stopped.";
  }
}

void MediaStreamImpl::requestUserMedia(
    const WebKit::WebUserMediaRequest& user_media_request) {
  // Save histogram data so we can see how much GetUserMedia is used.
  // The histogram counts the number of calls to the JS API
  // webGetUserMedia.
  UpdateWebRTCMethodCount(WEBKIT_GET_USER_MEDIA);
  DCHECK(CalledOnValidThread());
  int request_id = g_next_request_id++;
  StreamOptions options(MEDIA_NO_SERVICE, MEDIA_NO_SERVICE);
  WebKit::WebFrame* frame = NULL;
  GURL security_origin;

  // |user_media_request| can't be mocked. So in order to test at all we check
  // if it isNull.
  if (user_media_request.isNull()) {
    // We are in a test.
    options.audio_type = MEDIA_DEVICE_AUDIO_CAPTURE;
    options.video_type = MEDIA_DEVICE_VIDEO_CAPTURE;
  } else {
    if (user_media_request.audio()) {
      options.audio_type = MEDIA_DEVICE_AUDIO_CAPTURE;
      options.audio_device_id = GetStreamConstraint(
          user_media_request.audioConstraints(),
          kMediaStreamSourceInfoId, false);
    }
    if (user_media_request.video()) {
      options.video_type = MEDIA_DEVICE_VIDEO_CAPTURE;
      options.video_device_id = GetStreamConstraint(
          user_media_request.videoConstraints(),
          kMediaStreamSourceInfoId, false);
    }

    security_origin = GURL(user_media_request.securityOrigin().toString());
    // Get the WebFrame that requested a MediaStream.
    // The frame is needed to tell the MediaStreamDispatcher when a stream goes
    // out of scope.
    frame = user_media_request.ownerDocument().frame();
    DCHECK(frame);

    UpdateRequestOptions(user_media_request, &options);
  }

  DVLOG(1) << "MediaStreamImpl::requestUserMedia(" << request_id << ", [ "
           << "audio=" << (options.audio_type)
           << ", video=" << (options.video_type) << " ], "
           << security_origin.spec() << ")";

  user_media_requests_.push_back(
      new UserMediaRequestInfo(request_id, frame, user_media_request));

  media_stream_dispatcher_->GenerateStream(
      request_id,
      AsWeakPtr(),
      options,
      security_origin);
}

void MediaStreamImpl::cancelUserMediaRequest(
    const WebKit::WebUserMediaRequest& user_media_request) {
  DCHECK(CalledOnValidThread());
  UserMediaRequestInfo* request = FindUserMediaRequestInfo(user_media_request);
  if (request) {
    // We can't abort the stream generation process.
    // Instead, erase the request. Once the stream is generated we will stop the
    // stream if the request does not exist.
    DeleteUserMediaRequestInfo(request);
  }
}

WebKit::WebMediaStream MediaStreamImpl::GetMediaStream(
    const GURL& url) {
  return WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url);
}

bool MediaStreamImpl::IsMediaStream(const GURL& url) {
  WebKit::WebMediaStream web_stream(
      WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url));

  if (web_stream.isNull() || !web_stream.extraData())
    return false;  // This is not a valid stream.

  webrtc::MediaStreamInterface* stream = GetNativeMediaStream(web_stream);
  return (stream &&
      (!stream->GetVideoTracks().empty() || !stream->GetAudioTracks().empty()));
}

scoped_refptr<VideoFrameProvider>
MediaStreamImpl::GetVideoFrameProvider(
    const GURL& url,
    const base::Closure& error_cb,
    const VideoFrameProvider::RepaintCB& repaint_cb) {
  DCHECK(CalledOnValidThread());
  WebKit::WebMediaStream web_stream(GetMediaStream(url));

  if (web_stream.isNull() || !web_stream.extraData())
    return NULL;  // This is not a valid stream.

  DVLOG(1) << "MediaStreamImpl::GetVideoFrameProvider stream:"
           << UTF16ToUTF8(web_stream.id());

  webrtc::MediaStreamInterface* stream = GetNativeMediaStream(web_stream);
  if (stream)
    return CreateVideoFrameProvider(stream, error_cb, repaint_cb);
  NOTREACHED();
  return NULL;
}

scoped_refptr<MediaStreamAudioRenderer>
MediaStreamImpl::GetAudioRenderer(const GURL& url) {
  DCHECK(CalledOnValidThread());
  WebKit::WebMediaStream web_stream(GetMediaStream(url));

  if (web_stream.isNull() || !web_stream.extraData())
    return NULL;  // This is not a valid stream.

  DVLOG(1) << "MediaStreamImpl::GetAudioRenderer stream:"
           << UTF16ToUTF8(web_stream.id());

  MediaStreamExtraData* extra_data =
      static_cast<MediaStreamExtraData*>(web_stream.extraData());

  if (extra_data->is_local()) {
    // Create the local audio renderer if the stream contains audio tracks.
    return CreateLocalAudioRenderer(extra_data->stream().get());
  }

  webrtc::MediaStreamInterface* stream = extra_data->stream().get();
  if (!stream || stream->GetAudioTracks().empty())
    return NULL;

  // This is a remote media stream.
  WebRtcAudioDeviceImpl* audio_device =
      dependency_factory_->GetWebRtcAudioDevice();

  // Share the existing renderer if any, otherwise create a new one.
  scoped_refptr<WebRtcAudioRenderer> renderer(audio_device->renderer());
  if (!renderer.get()) {
    renderer = CreateRemoteAudioRenderer(extra_data->stream().get());

    if (renderer.get() && !audio_device->SetAudioRenderer(renderer.get()))
      renderer = NULL;
  }
  return renderer;
}

// Callback from MediaStreamDispatcher.
// The requested stream have been generated by the MediaStreamDispatcher.
void MediaStreamImpl::OnStreamGenerated(
    int request_id,
    const std::string& label,
    const StreamDeviceInfoArray& audio_array,
    const StreamDeviceInfoArray& video_array) {
  DCHECK(CalledOnValidThread());
  DVLOG(1) << "MediaStreamImpl::OnStreamGenerated stream:" << label;

  UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id);
  if (!request_info) {
    // This can happen if the request is canceled or the frame reloads while
    // MediaStreamDispatcher is processing the request.
    // We need to tell the dispatcher to stop the stream.
    media_stream_dispatcher_->StopStream(label);
    DVLOG(1) << "Request ID not found";
    return;
  }
  request_info->generated = true;

  WebKit::WebVector<WebKit::WebMediaStreamSource> audio_source_vector(
      audio_array.size());
  CreateWebKitSourceVector(label, audio_array,
                           WebKit::WebMediaStreamSource::TypeAudio,
                           audio_source_vector);
  request_info->audio_sources.assign(audio_source_vector);
  WebKit::WebVector<WebKit::WebMediaStreamSource> video_source_vector(
      video_array.size());
  CreateWebKitSourceVector(label, video_array,
                           WebKit::WebMediaStreamSource::TypeVideo,
                           video_source_vector);
  request_info->video_sources.assign(video_source_vector);

  WebKit::WebUserMediaRequest* request = &(request_info->request);
  WebKit::WebString webkit_id = UTF8ToUTF16(label);
  WebKit::WebMediaStream* web_stream = &(request_info->web_stream);

  WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_track_vector(
      audio_array.size());
  for (size_t i = 0; i < audio_track_vector.size(); ++i) {
    audio_track_vector[i].initialize(audio_source_vector[i].id(),
                                     audio_source_vector[i]);
  }

  WebKit::WebVector<WebKit::WebMediaStreamTrack> video_track_vector(
      video_array.size());
  for (size_t i = 0; i < video_track_vector.size(); ++i) {
    video_track_vector[i].initialize(video_source_vector[i].id(),
                                     video_source_vector[i]);
  }

  web_stream->initialize(webkit_id, audio_track_vector,
                         video_track_vector);

  // WebUserMediaRequest don't have an implementation in unit tests.
  // Therefore we need to check for isNull here.
  WebKit::WebMediaConstraints audio_constraints = request->isNull() ?
      WebKit::WebMediaConstraints() : request->audioConstraints();
  WebKit::WebMediaConstraints video_constraints = request->isNull() ?
      WebKit::WebMediaConstraints() : request->videoConstraints();

  dependency_factory_->CreateNativeMediaSources(
      RenderViewObserver::routing_id(),
      audio_constraints, video_constraints, web_stream,
      base::Bind(&MediaStreamImpl::OnCreateNativeSourcesComplete, AsWeakPtr()));
}

// Callback from MediaStreamDispatcher.
// The requested stream failed to be generated.
void MediaStreamImpl::OnStreamGenerationFailed(int request_id) {
  DCHECK(CalledOnValidThread());
  DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed("
           << request_id << ")";
  UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id);
  if (!request_info) {
    // This can happen if the request is canceled or the frame reloads while
    // MediaStreamDispatcher is processing the request.
    DVLOG(1) << "Request ID not found";
    return;
  }
  CompleteGetUserMediaRequest(request_info->web_stream,
                              &request_info->request,
                              false);
  DeleteUserMediaRequestInfo(request_info);
}

// Callback from MediaStreamDependencyFactory when the sources in |web_stream|
// have been generated.
void MediaStreamImpl::OnCreateNativeSourcesComplete(
    WebKit::WebMediaStream* web_stream,
    bool request_succeeded) {
  UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(web_stream);
  if (!request_info) {
    // This can happen if the request is canceled or the frame reloads while
    // MediaStreamDependencyFactory is creating the sources.
    DVLOG(1) << "Request ID not found";
    return;
  }

  // Create a native representation of the stream.
  if (request_succeeded) {
    dependency_factory_->CreateNativeLocalMediaStream(
        web_stream,
        base::Bind(&MediaStreamImpl::OnLocalMediaStreamStop, AsWeakPtr()));
  }
  CompleteGetUserMediaRequest(request_info->web_stream, &request_info->request,
                              request_succeeded);
  if (!request_succeeded) {
    OnLocalMediaStreamStop(UTF16ToUTF8(web_stream->id()));
  }
}

void MediaStreamImpl::OnDevicesEnumerated(
    int request_id,
    const StreamDeviceInfoArray& device_array) {
  DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated("
           << request_id << ")";
  NOTIMPLEMENTED();
}

void MediaStreamImpl::OnDevicesEnumerationFailed(int request_id) {
  DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerationFailed("
           << request_id << ")";
  NOTIMPLEMENTED();
}

void MediaStreamImpl::OnDeviceOpened(
    int request_id,
    const std::string& label,
    const StreamDeviceInfo& video_device) {
  DVLOG(1) << "MediaStreamImpl::OnDeviceOpened("
           << request_id << ", " << label << ")";
  NOTIMPLEMENTED();
}

void MediaStreamImpl::OnDeviceOpenFailed(int request_id) {
  DVLOG(1) << "MediaStreamImpl::VideoDeviceOpenFailed("
           << request_id << ")";
  NOTIMPLEMENTED();
}

void MediaStreamImpl::CompleteGetUserMediaRequest(
    const WebKit::WebMediaStream& stream,
    WebKit::WebUserMediaRequest* request_info,
    bool request_succeeded) {
  if (request_succeeded) {
    request_info->requestSucceeded(stream);
  } else {
    request_info->requestFailed();
  }
}

MediaStreamImpl::UserMediaRequestInfo*
MediaStreamImpl::FindUserMediaRequestInfo(int request_id) {
  UserMediaRequests::iterator it = user_media_requests_.begin();
  for (; it != user_media_requests_.end(); ++it) {
    if ((*it)->request_id == request_id)
      return (*it);
  }
  return NULL;
}

MediaStreamImpl::UserMediaRequestInfo*
MediaStreamImpl::FindUserMediaRequestInfo(
    const WebKit::WebUserMediaRequest& request) {
  UserMediaRequests::iterator it = user_media_requests_.begin();
  for (; it != user_media_requests_.end(); ++it) {
    if ((*it)->request == request)
      return (*it);
  }
  return NULL;
}

MediaStreamImpl::UserMediaRequestInfo*
MediaStreamImpl::FindUserMediaRequestInfo(const std::string& label) {
  UserMediaRequests::iterator it = user_media_requests_.begin();
  for (; it != user_media_requests_.end(); ++it) {
    if ((*it)->generated && (*it)->web_stream.id() == UTF8ToUTF16(label))
      return (*it);
  }
  return NULL;
}

MediaStreamImpl::UserMediaRequestInfo*
MediaStreamImpl::FindUserMediaRequestInfo(
    WebKit::WebMediaStream* web_stream) {
  UserMediaRequests::iterator it = user_media_requests_.begin();
  for (; it != user_media_requests_.end(); ++it) {
    if (&((*it)->web_stream) == web_stream)
      return  (*it);
  }
  return NULL;
}

void MediaStreamImpl::DeleteUserMediaRequestInfo(
    UserMediaRequestInfo* request) {
  UserMediaRequests::iterator it = user_media_requests_.begin();
  for (; it != user_media_requests_.end(); ++it) {
    if ((*it) == request) {
      user_media_requests_.erase(it);
      return;
    }
  }
  NOTREACHED();
}

void MediaStreamImpl::FrameDetached(WebKit::WebFrame* frame) {
  // Do same thing as FrameWillClose.
  FrameWillClose(frame);
}

void MediaStreamImpl::FrameWillClose(WebKit::WebFrame* frame) {
  // Loop through all UserMediaRequests and find the requests that belong to the
  // frame that is being closed.
  UserMediaRequests::iterator request_it = user_media_requests_.begin();

  while (request_it != user_media_requests_.end()) {
    if ((*request_it)->frame == frame) {
      DVLOG(1) << "MediaStreamImpl::FrameWillClose: "
               << "Cancel user media request " << (*request_it)->request_id;
      // If the request is generated, it means that the MediaStreamDispatcher
      // has generated a stream for us and we need to let the
      // MediaStreamDispatcher know that the stream is no longer wanted.
      // If not, we cancel the request and delete the request object.
      if ((*request_it)->generated) {
        // Stop the local audio track before closing the device in the browser.
        StopLocalAudioTrack((*request_it)->web_stream);

        media_stream_dispatcher_->StopStream(
            UTF16ToUTF8((*request_it)->web_stream.id()));
      } else {
        media_stream_dispatcher_->CancelGenerateStream(
            (*request_it)->request_id, AsWeakPtr());
      }
      request_it = user_media_requests_.erase(request_it);
    } else {
      ++request_it;
    }
  }
}

scoped_refptr<VideoFrameProvider>
MediaStreamImpl::CreateVideoFrameProvider(
    webrtc::MediaStreamInterface* stream,
    const base::Closure& error_cb,
    const VideoFrameProvider::RepaintCB& repaint_cb) {
  if (stream->GetVideoTracks().empty())
    return NULL;

  DVLOG(1) << "MediaStreamImpl::CreateRemoteVideoFrameProvider label:"
           << stream->label();

  return new RTCVideoRenderer(
      stream->GetVideoTracks()[0],
      error_cb,
      repaint_cb);
}

scoped_refptr<WebRtcAudioRenderer> MediaStreamImpl::CreateRemoteAudioRenderer(
    webrtc::MediaStreamInterface* stream) {
  if (stream->GetAudioTracks().empty())
    return NULL;

  DVLOG(1) << "MediaStreamImpl::CreateRemoteAudioRenderer label:"
           << stream->label();

  return new WebRtcAudioRenderer(RenderViewObserver::routing_id());
}

scoped_refptr<WebRtcLocalAudioRenderer>
MediaStreamImpl::CreateLocalAudioRenderer(
    webrtc::MediaStreamInterface* stream) {
  if (stream->GetAudioTracks().empty())
    return NULL;

  DVLOG(1) << "MediaStreamImpl::CreateLocalAudioRenderer label:"
           << stream->label();

  webrtc::AudioTrackVector audio_tracks = stream->GetAudioTracks();
  DCHECK_EQ(audio_tracks.size(), 1u);
  webrtc::AudioTrackInterface* audio_track = audio_tracks[0];
  DVLOG(1) << "audio_track.kind   : " << audio_track->kind()
           << "audio_track.id     : " << audio_track->id()
           << "audio_track.enabled: " << audio_track->enabled();

  // Create a new WebRtcLocalAudioRenderer instance and connect it to the
  // existing WebRtcAudioCapturer so that the renderer can use it as source.
  return new WebRtcLocalAudioRenderer(
      static_cast<WebRtcLocalAudioTrack*>(audio_track),
      RenderViewObserver::routing_id());
}

void MediaStreamImpl::StopLocalAudioTrack(
    const WebKit::WebMediaStream& web_stream) {
  MediaStreamExtraData* extra_data = static_cast<MediaStreamExtraData*>(
      web_stream.extraData());
  if (extra_data && extra_data->is_local() && extra_data->stream().get() &&
      !extra_data->stream()->GetAudioTracks().empty()) {
    webrtc::AudioTrackVector audio_tracks =
        extra_data->stream()->GetAudioTracks();
    for (size_t i = 0; i < audio_tracks.size(); ++i) {
      WebRtcLocalAudioTrack* audio_track = static_cast<WebRtcLocalAudioTrack*>(
          audio_tracks[i].get());
      // Remove the WebRtcAudioDevice as the sink to the local audio track.
      audio_track->RemoveSink(dependency_factory_->GetWebRtcAudioDevice());
      // Stop the audio track. This will unhook the audio track from the
      // capturer and will shutdown the source of the capturer if it is the
      // last audio track connecting to the capturer.
      audio_track->Stop();
    }
  }
}

MediaStreamSourceExtraData::MediaStreamSourceExtraData(
    const StreamDeviceInfo& device_info,
    const WebKit::WebMediaStreamSource& webkit_source)
    : device_info_(device_info),
      webkit_source_(webkit_source) {
}

MediaStreamSourceExtraData::MediaStreamSourceExtraData(
    media::AudioCapturerSource* source)
    : audio_source_(source)  {
}

MediaStreamSourceExtraData::~MediaStreamSourceExtraData() {}

MediaStreamExtraData::MediaStreamExtraData(
    webrtc::MediaStreamInterface* stream, bool is_local)
    : stream_(stream),
      is_local_(is_local) {
}

MediaStreamExtraData::~MediaStreamExtraData() {
}

void MediaStreamExtraData::SetLocalStreamStopCallback(
    const StreamStopCallback& stop_callback) {
  stream_stop_callback_ = stop_callback;
}

void MediaStreamExtraData::OnLocalStreamStop() {
  if (!stream_stop_callback_.is_null())
    stream_stop_callback_.Run(stream_->label());
}

MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo()
    : request_id(0), generated(false), frame(NULL), request() {
}

MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo(
    int request_id,
    WebKit::WebFrame* frame,
    const WebKit::WebUserMediaRequest& request)
    : request_id(request_id), generated(false), frame(frame),
      request(request) {
}

MediaStreamImpl::UserMediaRequestInfo::~UserMediaRequestInfo() {
  // Release the extra data field of all sources created by
  // MediaStreamImpl for this request. This breaks the circular reference to
  // WebKit::MediaStreamSource.
  // TODO(tommyw): Remove this once WebKit::MediaStreamSource::Owner has been
  // implemented to fully avoid a circular dependency.
  for (size_t i = 0; i < audio_sources.size(); ++i) {
    audio_sources[i].setReadyState(
        WebKit::WebMediaStreamSource::ReadyStateEnded);
    audio_sources[i].setExtraData(NULL);
  }

  for (size_t i = 0; i < video_sources.size(); ++i) {
    video_sources[i].setReadyState(
            WebKit::WebMediaStreamSource::ReadyStateEnded);
    video_sources[i].setExtraData(NULL);
  }
}

}  // namespace content
