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_USER_MEDIA_CLIENT_IMPL_H_ 6 #define CONTENT_RENDERER_MEDIA_USER_MEDIA_CLIENT_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_frame_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/WebSourceInfo.h" 25 #include "third_party/WebKit/public/platform/WebVector.h" 26 #include "third_party/WebKit/public/web/WebMediaDevicesRequest.h" 27 #include "third_party/WebKit/public/web/WebUserMediaClient.h" 28 #include "third_party/WebKit/public/web/WebUserMediaRequest.h" 29 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" 30 31 namespace content { 32 class PeerConnectionDependencyFactory; 33 class MediaStreamDispatcher; 34 class MediaStreamVideoSource; 35 class VideoCapturerDelegate; 36 37 // UserMediaClientImpl is a delegate for the Media Stream GetUserMedia API. 38 // It ties together WebKit and MediaStreamManager 39 // (via MediaStreamDispatcher and MediaStreamDispatcherHost) 40 // in the browser process. It must be created, called and destroyed on the 41 // render thread. 42 class CONTENT_EXPORT UserMediaClientImpl 43 : public RenderFrameObserver, 44 NON_EXPORTED_BASE(public blink::WebUserMediaClient), 45 public MediaStreamDispatcherEventHandler, 46 NON_EXPORTED_BASE(public base::NonThreadSafe) { 47 public: 48 // |render_frame| and |dependency_factory| must outlive this instance. 49 UserMediaClientImpl( 50 RenderFrame* render_frame, 51 PeerConnectionDependencyFactory* dependency_factory, 52 scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher); 53 virtual ~UserMediaClientImpl(); 54 55 MediaStreamDispatcher* media_stream_dispatcher() const { 56 return media_stream_dispatcher_.get(); 57 } 58 59 // blink::WebUserMediaClient implementation 60 virtual void requestUserMedia( 61 const blink::WebUserMediaRequest& user_media_request); 62 virtual void cancelUserMediaRequest( 63 const blink::WebUserMediaRequest& user_media_request); 64 virtual void requestMediaDevices( 65 const blink::WebMediaDevicesRequest& media_devices_request) OVERRIDE; 66 virtual void cancelMediaDevicesRequest( 67 const blink::WebMediaDevicesRequest& media_devices_request) OVERRIDE; 68 virtual void requestSources( 69 const blink::WebMediaStreamTrackSourcesRequest& sources_request) OVERRIDE; 70 71 // MediaStreamDispatcherEventHandler implementation. 72 virtual void OnStreamGenerated( 73 int request_id, 74 const std::string& label, 75 const StreamDeviceInfoArray& audio_array, 76 const StreamDeviceInfoArray& video_array) OVERRIDE; 77 virtual void OnStreamGenerationFailed( 78 int request_id, 79 MediaStreamRequestResult result) OVERRIDE; 80 virtual void OnDeviceStopped(const std::string& label, 81 const StreamDeviceInfo& device_info) OVERRIDE; 82 virtual void OnDevicesEnumerated( 83 int request_id, 84 const StreamDeviceInfoArray& device_array) OVERRIDE; 85 virtual void OnDeviceOpened( 86 int request_id, 87 const std::string& label, 88 const StreamDeviceInfo& device_info) OVERRIDE; 89 virtual void OnDeviceOpenFailed(int request_id) OVERRIDE; 90 91 // RenderFrameObserver OVERRIDE 92 virtual void FrameWillClose() OVERRIDE; 93 94 protected: 95 // Called when |source| has been stopped from JavaScript. 96 void OnLocalSourceStopped(const blink::WebMediaStreamSource& source); 97 98 // These methods are virtual for test purposes. A test can override them to 99 // test requesting local media streams. The function notifies WebKit that the 100 // |request| have completed. 101 virtual void GetUserMediaRequestSucceeded( 102 const blink::WebMediaStream& stream, 103 blink::WebUserMediaRequest* request_info); 104 virtual void GetUserMediaRequestFailed( 105 blink::WebUserMediaRequest* request_info, 106 MediaStreamRequestResult result); 107 virtual void GetUserMediaRequestTrackStartedFailed( 108 blink::WebUserMediaRequest* request_info, 109 MediaStreamRequestResult result, 110 const blink::WebString& result_name); 111 virtual void EnumerateDevicesSucceded( 112 blink::WebMediaDevicesRequest* request, 113 blink::WebVector<blink::WebMediaDeviceInfo>& devices); 114 virtual void EnumerateSourcesSucceded( 115 blink::WebMediaStreamTrackSourcesRequest* request, 116 blink::WebVector<blink::WebSourceInfo>& sources); 117 // Creates a MediaStreamVideoSource object. 118 // This is virtual for test purposes. 119 virtual MediaStreamVideoSource* CreateVideoSource( 120 const StreamDeviceInfo& device, 121 const MediaStreamSource::SourceStoppedCallback& stop_callback); 122 123 private: 124 // Class for storing information about a WebKit request to create a 125 // MediaStream. 126 class UserMediaRequestInfo 127 : public base::SupportsWeakPtr<UserMediaRequestInfo> { 128 public: 129 typedef base::Callback<void(UserMediaRequestInfo* request_info, 130 MediaStreamRequestResult result, 131 const blink::WebString& result_name)> 132 ResourcesReady; 133 134 UserMediaRequestInfo(int request_id, 135 const blink::WebUserMediaRequest& request, 136 bool enable_automatic_output_device_selection); 137 ~UserMediaRequestInfo(); 138 int request_id; 139 // True if MediaStreamDispatcher has generated the stream, see 140 // OnStreamGenerated. 141 bool generated; 142 const bool enable_automatic_output_device_selection; 143 blink::WebMediaStream web_stream; 144 blink::WebUserMediaRequest request; 145 146 void StartAudioTrack(const blink::WebMediaStreamTrack& track, 147 const blink::WebMediaConstraints& constraints); 148 149 blink::WebMediaStreamTrack CreateAndStartVideoTrack( 150 const blink::WebMediaStreamSource& source, 151 const blink::WebMediaConstraints& constraints); 152 153 // Triggers |callback| when all sources used in this request have either 154 // successfully started, or a source has failed to start. 155 void CallbackOnTracksStarted(const ResourcesReady& callback); 156 157 bool IsSourceUsed(const blink::WebMediaStreamSource& source) const; 158 void RemoveSource(const blink::WebMediaStreamSource& source); 159 160 bool HasPendingSources() const; 161 162 private: 163 void OnTrackStarted( 164 MediaStreamSource* source, 165 MediaStreamRequestResult result, 166 const blink::WebString& result_name); 167 void CheckAllTracksStarted(); 168 169 ResourcesReady ready_callback_; 170 MediaStreamRequestResult request_result_; 171 blink::WebString request_result_name_; 172 // Sources used in this request. 173 std::vector<blink::WebMediaStreamSource> sources_; 174 std::vector<MediaStreamSource*> sources_waiting_for_callback_; 175 }; 176 typedef ScopedVector<UserMediaRequestInfo> UserMediaRequests; 177 178 typedef std::vector<blink::WebMediaStreamSource> LocalStreamSources; 179 180 struct MediaDevicesRequestInfo; 181 typedef ScopedVector<MediaDevicesRequestInfo> MediaDevicesRequests; 182 183 // Creates a WebKit representation of stream sources based on 184 // |devices| from the MediaStreamDispatcher. 185 void InitializeSourceObject( 186 const StreamDeviceInfo& device, 187 blink::WebMediaStreamSource::Type type, 188 const blink::WebMediaConstraints& constraints, 189 blink::WebMediaStreamSource* webkit_source); 190 191 void CreateVideoTracks( 192 const StreamDeviceInfoArray& devices, 193 const blink::WebMediaConstraints& constraints, 194 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, 195 UserMediaRequestInfo* request); 196 197 void CreateAudioTracks( 198 const StreamDeviceInfoArray& devices, 199 const blink::WebMediaConstraints& constraints, 200 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks, 201 UserMediaRequestInfo* request); 202 203 // Callback function triggered when all native versions of the 204 // underlying media sources and tracks have been created and started. 205 void OnCreateNativeTracksCompleted( 206 UserMediaRequestInfo* request, 207 MediaStreamRequestResult result, 208 const blink::WebString& result_name); 209 210 void OnStreamGeneratedForCancelledRequest( 211 const StreamDeviceInfoArray& audio_array, 212 const StreamDeviceInfoArray& video_array); 213 214 void FinalizeEnumerateDevices(MediaDevicesRequestInfo* request); 215 void FinalizeEnumerateSources(MediaDevicesRequestInfo* request); 216 217 UserMediaRequestInfo* FindUserMediaRequestInfo(int request_id); 218 UserMediaRequestInfo* FindUserMediaRequestInfo( 219 const blink::WebUserMediaRequest& request); 220 void DeleteUserMediaRequestInfo(UserMediaRequestInfo* request); 221 void DeleteAllUserMediaRequests(); 222 223 MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(int request_id); 224 MediaDevicesRequestInfo* FindMediaDevicesRequestInfo( 225 const blink::WebMediaDevicesRequest& request); 226 void CancelAndDeleteMediaDevicesRequest(MediaDevicesRequestInfo* request); 227 228 // Returns the source that use a device with |device.session_id| 229 // and |device.device.id|. NULL if such source doesn't exist. 230 const blink::WebMediaStreamSource* FindLocalSource( 231 const StreamDeviceInfo& device) const; 232 233 void StopLocalSource(const blink::WebMediaStreamSource& source, 234 bool notify_dispatcher); 235 236 // Weak ref to a PeerConnectionDependencyFactory, owned by the RenderThread. 237 // It's valid for the lifetime of RenderThread. 238 // TODO(xians): Remove this dependency once audio do not need it for local 239 // audio. 240 PeerConnectionDependencyFactory* const dependency_factory_; 241 242 // UserMediaClientImpl owns MediaStreamDispatcher instead of RenderFrameImpl 243 // (or RenderFrameObserver) to ensure tear-down occurs in the right order. 244 const scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher_; 245 246 LocalStreamSources local_sources_; 247 248 UserMediaRequests user_media_requests_; 249 250 // Requests to enumerate media devices. 251 MediaDevicesRequests media_devices_requests_; 252 253 // Note: This member must be the last to ensure all outstanding weak pointers 254 // are invalidated first. 255 base::WeakPtrFactory<UserMediaClientImpl> weak_factory_; 256 257 DISALLOW_COPY_AND_ASSIGN(UserMediaClientImpl); 258 }; 259 260 } // namespace content 261 262 #endif // CONTENT_RENDERER_MEDIA_USER_MEDIA_CLIENT_IMPL_H_ 263