| Index: content/renderer/media/media_stream_source.cc | 
| diff --git a/content/renderer/media/media_stream_source.cc b/content/renderer/media/media_stream_source.cc | 
| index 8db26024403334efc43050ce36a75bc06301362b..d2b4cbf7f9bac1af284e581a6887e78578ff08ec 100644 | 
| --- a/content/renderer/media/media_stream_source.cc | 
| +++ b/content/renderer/media/media_stream_source.cc | 
| @@ -13,14 +13,41 @@ const char MediaStreamSource::kSourceId[] = "sourceId"; | 
| MediaStreamSource::MediaStreamSource() { | 
| } | 
|  | 
| -MediaStreamSource::~MediaStreamSource() {} | 
| +MediaStreamSource::~MediaStreamSource() { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  RunStopCallbackAndEndStream(); | 
| +} | 
|  | 
| void MediaStreamSource::StopSource() { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| DoStopSource(); | 
| +  RunStopCallbackAndEndStream(); | 
| +} | 
| + | 
| +void MediaStreamSource::SetDeviceInfo(const StreamDeviceInfo& device_info) { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  device_info_ = device_info; | 
| +} | 
| + | 
| +void MediaStreamSource::SetStopCallback( | 
| +    const SourceStoppedCallback& stop_callback) { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  DCHECK(stop_callback_.is_null()); | 
| +  stop_callback_ = stop_callback; | 
| +} | 
| + | 
| +void MediaStreamSource::ResetSourceStoppedCallback() { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| +  DCHECK(!stop_callback_.is_null()); | 
| +  stop_callback_.Reset(); | 
| +} | 
| + | 
| +void MediaStreamSource::RunStopCallbackAndEndStream() { | 
| +  DCHECK(thread_checker_.CalledOnValidThread()); | 
| if (!stop_callback_.is_null()) | 
| base::ResetAndReturn(&stop_callback_).Run(owner()); | 
| - | 
| -  owner().setReadyState(blink::WebMediaStreamSource::ReadyStateEnded); | 
| +  if (!owner().isNull()) | 
| +    owner().setReadyState(blink::WebMediaStreamSource::ReadyStateEnded); | 
| } | 
|  | 
| }  // namespace content | 
|  |