1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_ 6 #define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/compiler_specific.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_vector.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/threading/non_thread_safe.h" 18 #include "content/common/content_export.h" 19 #include "content/public/renderer/render_view_observer.h" 20 #include "content/renderer/media/media_stream_dispatcher_eventhandler.h" 21 #include "content/renderer/media/media_stream_source.h" 22 #include "third_party/WebKit/public/platform/WebMediaStream.h" 23 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 24 #include "third_party/WebKit/public/platform/WebVector.h" 25 #include "third_party/WebKit/public/web/WebMediaDevicesRequest.h" 26 #include "third_party/WebKit/public/web/WebUserMediaClient.h" 27 #include "third_party/WebKit/public/web/WebUserMediaRequest.h" 28 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" 29 30 namespace content { 31 class PeerConnectionDependencyFactory; 32 class MediaStreamDispatcher; 33 class MediaStreamVideoSource; 34 class VideoCapturerDelegate; 35 36 // MediaStreamImpl is a delegate for the Media Stream GetUserMedia API. 37 // It ties together WebKit and MediaStreamManager 38 // (via MediaStreamDispatcher and MediaStreamDispatcherHost) 39 // in the browser process. It must be created, called and destroyed on the 40 // render thread. 41 // MediaStreamImpl have weak pointers to a MediaStreamDispatcher. 42 class CONTENT_EXPORT MediaStreamImpl 43 : public RenderViewObserver, 44 NON_EXPORTED_BASE(public blink::WebUserMediaClient), 45 public MediaStreamDispatcherEventHandler, 46 public base::SupportsWeakPtr<MediaStreamImpl>, 47 NON_EXPORTED_BASE(public base::NonThreadSafe) { 48 public: 49 MediaStreamImpl( 50 RenderView* render_view, 51 MediaStreamDispatcher* media_stream_dispatcher, 52 PeerConnectionDependencyFactory* dependency_factory); 53 virtual ~MediaStreamImpl(); 54 55 // blink::WebUserMediaClient implementation 56 virtual void requestUserMedia( 57 const blink::WebUserMediaRequest& user_media_request); 58 virtual void cancelUserMediaRequest( 59 const blink::WebUserMediaRequest& user_media_request); 60 virtual void requestMediaDevices( 61 const blink::WebMediaDevicesRequest& media_devices_request) OVERRIDE; 62 virtual void cancelMediaDevicesRequest( 63 const blink::WebMediaDevicesRequest& media_devices_request) OVERRIDE; 64 65 // MediaStreamDispatcherEventHandler implementation. 66 virtual void OnStreamGenerated( 67 int request_id, 68 const std::string& label, 69 const StreamDeviceInfoArray& audio_array, 70 const StreamDeviceInfoArray& video_array) OVERRIDE; 71 virtual void OnStreamGenerationFailed( 72 int request_id, 73 content::MediaStreamRequestResult result) OVERRIDE; 74 virtual void OnDeviceStopped(const std::string& label, 75 const StreamDeviceInfo& device_info) OVERRIDE; 76 virtual void OnDevicesEnumerated( 77 int request_id, 78 const StreamDeviceInfoArray& device_array) OVERRIDE; 79 virtual void OnDeviceOpened( 80 int request_id, 81 const std::string& label, 82 const StreamDeviceInfo& device_info) OVERRIDE; 83 virtual void OnDeviceOpenFailed(int request_id) OVERRIDE; 84 85 // RenderViewObserver OVERRIDE 86 virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE; 87 virtual void FrameWillClose(blink::WebFrame* frame) OVERRIDE; 88 89 protected: 90 // Called when |source| has been stopped from JavaScript. 91 void OnLocalSourceStopped(const blink::WebMediaStreamSource& source); 92 93 // These methods are virtual for test purposes. A test can override them to 94 // test requesting local media streams. The function notifies WebKit that the 95 // |request| have completed. 96 virtual void GetUserMediaRequestSucceeded( 97 const blink::WebMediaStream& stream, 98 blink::WebUserMediaRequest* request_info); 99 virtual void GetUserMediaRequestFailed( 100 blink::WebUserMediaRequest* request_info, 101 content::MediaStreamRequestResult result); 102 virtual void EnumerateDevicesSucceded( 103 blink::WebMediaDevicesRequest* request, 104 blink::WebVector<blink::WebMediaDeviceInfo>& devices); 105 // Creates a MediaStreamVideoSource object. 106 // This is virtual for test purposes. 107 virtual MediaStreamVideoSource* CreateVideoSource( 108 const StreamDeviceInfo& device, 109 const MediaStreamSource::SourceStoppedCallback& stop_callback); 110 111 private: 112 // Class for storing information about a WebKit request to create a 113 // MediaStream. 114 class UserMediaRequestInfo 115 : public base::SupportsWeakPtr<UserMediaRequestInfo> { 116 public: 117 typedef base::Callback<void(UserMediaRequestInfo* request_info, 118 content::MediaStreamRequestResult result)> 119 ResourcesReady; 120 121 UserMediaRequestInfo(int request_id, 122 blink::WebFrame* frame, 123 const blink::WebUserMediaRequest& request, 124 bool enable_automatic_output_device_selection); 125 ~UserMediaRequestInfo(); 126 int request_id; 127 // True if MediaStreamDispatcher has generated the stream, see 128 // OnStreamGenerated. 129 bool generated; 130 const bool enable_automatic_output_device_selection; 131 blink::WebFrame* frame; // WebFrame that requested the MediaStream. 132 blink::WebMediaStream web_stream; 133 blink::WebUserMediaRequest request; 134 135 void StartAudioTrack(const blink::WebMediaStreamTrack& track, 136 const blink::WebMediaConstraints& constraints); 137 138 blink::WebMediaStreamTrack CreateAndStartVideoTrack( 139 const blink::WebMediaStreamSource& source, 140 const blink::WebMediaConstraints& constraints); 141 142 // Triggers |callback| when all sources used in this request have either 143 // successfully started, or a source has failed to start. 144 void CallbackOnTracksStarted(const ResourcesReady& callback); 145 146 bool IsSourceUsed(const blink::WebMediaStreamSource& source) const; 147 void RemoveSource(const blink::WebMediaStreamSource& source); 148 149 bool AreAllSourcesRemoved() const { return sources_.empty(); } 150 151 private: 152 void OnTrackStarted(MediaStreamSource* source, bool success); 153 void CheckAllTracksStarted(); 154 155 ResourcesReady ready_callback_; 156 bool request_failed_; 157 // Sources used in this request. 158 std::vector<blink::WebMediaStreamSource> sources_; 159 std::vector<MediaStreamSource*> sources_waiting_for_callback_; 160 }; 161 typedef ScopedVector<UserMediaRequestInfo> UserMediaRequests; 162 163 struct LocalStreamSource { 164 LocalStreamSource(blink::WebFrame* frame, 165 const blink::WebMediaStreamSource& source) 166 : frame(frame), source(source) { 167 } 168 // |frame| is the WebFrame that requested |source|. NULL in unit tests. 169 // TODO(perkj): Change so that |frame| is not NULL in unit tests. 170 blink::WebFrame* frame; 171 blink::WebMediaStreamSource source; 172 }; 173 typedef std::vector<LocalStreamSource> LocalStreamSources; 174 175 struct MediaDevicesRequestInfo; 176 typedef ScopedVector<MediaDevicesRequestInfo> MediaDevicesRequests; 177 178 // Creates a WebKit representation of stream sources based on 179 // |devices| from the MediaStreamDispatcher. 180 void InitializeSourceObject( 181 const StreamDeviceInfo& device, 182 blink::WebMediaStreamSource::Type type, 183 const blink::WebMediaConstraints& constraints, 184 blink::WebFrame* frame, 185 blink::WebMediaStreamSource* webkit_source); 186 187 void CreateVideoTracks( 188 const StreamDeviceInfoArray& devices, 189 const blink::WebMediaConstraints& constraints, 190 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, 191 UserMediaRequestInfo* request); 192 193 void CreateAudioTracks( 194 const StreamDeviceInfoArray& devices, 195 const blink::WebMediaConstraints& constraints, 196 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, 197 UserMediaRequestInfo* request); 198 199 // Callback function triggered when all native versions of the 200 // underlying media sources and tracks have been created and started. 201 void OnCreateNativeTracksCompleted( 202 UserMediaRequestInfo* request, 203 content::MediaStreamRequestResult result); 204 205 UserMediaRequestInfo* FindUserMediaRequestInfo(int request_id); 206 UserMediaRequestInfo* FindUserMediaRequestInfo( 207 const blink::WebUserMediaRequest& request); 208 void DeleteUserMediaRequestInfo(UserMediaRequestInfo* request); 209 210 MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(int request_id); 211 MediaDevicesRequestInfo* FindMediaDevicesRequestInfo( 212 const blink::WebMediaDevicesRequest& request); 213 void DeleteMediaDevicesRequestInfo(MediaDevicesRequestInfo* request); 214 215 // Returns the source that use a device with |device.session_id| 216 // and |device.device.id|. NULL if such source doesn't exist. 217 const blink::WebMediaStreamSource* FindLocalSource( 218 const StreamDeviceInfo& device) const; 219 220 void StopLocalSource(const blink::WebMediaStreamSource& source, 221 bool notify_dispatcher); 222 223 // Weak ref to a PeerConnectionDependencyFactory, owned by the RenderThread. 224 // It's valid for the lifetime of RenderThread. 225 // TODO(xians): Remove this dependency once audio do not need it for local 226 // audio. 227 PeerConnectionDependencyFactory* dependency_factory_; 228 229 // media_stream_dispatcher_ is a weak reference, owned by RenderView. It's 230 // valid for the lifetime of RenderView. 231 MediaStreamDispatcher* media_stream_dispatcher_; 232 233 LocalStreamSources local_sources_; 234 235 UserMediaRequests user_media_requests_; 236 237 // Requests to enumerate media devices. 238 MediaDevicesRequests media_devices_requests_; 239 240 DISALLOW_COPY_AND_ASSIGN(MediaStreamImpl); 241 }; 242 243 } // namespace content 244 245 #endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_ 246