blob: ad960201f361df85e1c55c96ba6b3241288ae89e [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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"
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000021#include "content/renderer/media/media_stream_source.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010022#include "third_party/WebKit/public/platform/WebMediaStream.h"
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +010023#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
24#include "third_party/WebKit/public/platform/WebVector.h"
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +010025#include "third_party/WebKit/public/web/WebMediaDevicesRequest.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010026#include "third_party/WebKit/public/web/WebUserMediaClient.h"
27#include "third_party/WebKit/public/web/WebUserMediaRequest.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000028#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000029
30namespace content {
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010031class PeerConnectionDependencyFactory;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000032class MediaStreamDispatcher;
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000033class MediaStreamVideoSource;
34class VideoCapturerDelegate;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000035
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010036// MediaStreamImpl is a delegate for the Media Stream GetUserMedia API.
37// It ties together WebKit and MediaStreamManager
38// (via MediaStreamDispatcher and MediaStreamDispatcherHost)
Torne (Richard Coles)58218062012-11-14 11:43:16 +000039// in the browser process. It must be created, called and destroyed on the
40// render thread.
41// MediaStreamImpl have weak pointers to a MediaStreamDispatcher.
42class CONTENT_EXPORT MediaStreamImpl
43 : public RenderViewObserver,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000044 NON_EXPORTED_BASE(public blink::WebUserMediaClient),
Torne (Richard Coles)58218062012-11-14 11:43:16 +000045 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,
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010052 PeerConnectionDependencyFactory* dependency_factory);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000053 virtual ~MediaStreamImpl();
54
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000055 // blink::WebUserMediaClient implementation
Torne (Richard Coles)58218062012-11-14 11:43:16 +000056 virtual void requestUserMedia(
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010057 const blink::WebUserMediaRequest& user_media_request);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000058 virtual void cancelUserMediaRequest(
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010059 const blink::WebUserMediaRequest& user_media_request);
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +010060 virtual void requestMediaDevices(
61 const blink::WebMediaDevicesRequest& media_devices_request) OVERRIDE;
62 virtual void cancelMediaDevicesRequest(
63 const blink::WebMediaDevicesRequest& media_devices_request) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000064
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;
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000071 virtual void OnStreamGenerationFailed(
72 int request_id,
73 content::MediaStreamRequestResult result) OVERRIDE;
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000074 virtual void OnDeviceStopped(const std::string& label,
75 const StreamDeviceInfo& device_info) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000076 virtual void OnDevicesEnumerated(
77 int request_id,
78 const StreamDeviceInfoArray& device_array) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000079 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
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000086 virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE;
87 virtual void FrameWillClose(blink::WebFrame* frame) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000088
89 protected:
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000090 // Called when |source| has been stopped from JavaScript.
91 void OnLocalSourceStopped(const blink::WebMediaStreamSource& source);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +010092
Ben Murdoch0529e5d2014-04-24 10:50:13 +010093 // These methods are virtual for test purposes. A test can override them to
Torne (Richard Coles)58218062012-11-14 11:43:16 +000094 // test requesting local media streams. The function notifies WebKit that the
Ben Murdoch0529e5d2014-04-24 10:50:13 +010095 // |request| have completed.
96 virtual void GetUserMediaRequestSucceeded(
97 const blink::WebMediaStream& stream,
98 blink::WebUserMediaRequest* request_info);
99 virtual void GetUserMediaRequestFailed(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000100 blink::WebUserMediaRequest* request_info,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000101 content::MediaStreamRequestResult result);
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100102 virtual void EnumerateDevicesSucceded(
103 blink::WebMediaDevicesRequest* request,
104 blink::WebVector<blink::WebMediaDeviceInfo>& devices);
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000105 // 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
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000111 private:
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000112 // Class for storing information about a WebKit request to create a
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000113 // MediaStream.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000114 class UserMediaRequestInfo
115 : public base::SupportsWeakPtr<UserMediaRequestInfo> {
116 public:
117 typedef base::Callback<void(UserMediaRequestInfo* request_info,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000118 content::MediaStreamRequestResult result)>
119 ResourcesReady;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000120
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000121 UserMediaRequestInfo(int request_id,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000122 blink::WebFrame* frame,
123 const blink::WebUserMediaRequest& request,
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100124 bool enable_automatic_output_device_selection);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100125 ~UserMediaRequestInfo();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000126 int request_id;
127 // True if MediaStreamDispatcher has generated the stream, see
128 // OnStreamGenerated.
129 bool generated;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100130 const bool enable_automatic_output_device_selection;
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000131 blink::WebFrame* frame; // WebFrame that requested the MediaStream.
132 blink::WebMediaStream web_stream;
133 blink::WebUserMediaRequest request;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000134
Ben Murdocheffb81e2014-03-31 11:51:25 +0100135 void StartAudioTrack(const blink::WebMediaStreamTrack& track,
136 const blink::WebMediaConstraints& constraints);
137
138 blink::WebMediaStreamTrack CreateAndStartVideoTrack(
139 const blink::WebMediaStreamSource& source,
Torne (Richard Coles)cedac222014-06-03 10:58:34 +0100140 const blink::WebMediaConstraints& constraints);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000141
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
Torne (Richard Coles)cedac222014-06-03 10:58:34 +0100149 bool AreAllSourcesRemoved() const { return sources_.empty(); }
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000150
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_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000160 };
161 typedef ScopedVector<UserMediaRequestInfo> UserMediaRequests;
162
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100163 struct LocalStreamSource {
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000164 LocalStreamSource(blink::WebFrame* frame,
165 const blink::WebMediaStreamSource& source)
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100166 : 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.
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000170 blink::WebFrame* frame;
171 blink::WebMediaStreamSource source;
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100172 };
173 typedef std::vector<LocalStreamSource> LocalStreamSources;
174
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100175 struct MediaDevicesRequestInfo;
176 typedef ScopedVector<MediaDevicesRequestInfo> MediaDevicesRequests;
177
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100178 // Creates a WebKit representation of stream sources based on
179 // |devices| from the MediaStreamDispatcher.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000180 void InitializeSourceObject(
181 const StreamDeviceInfo& device,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000182 blink::WebMediaStreamSource::Type type,
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000183 const blink::WebMediaConstraints& constraints,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000184 blink::WebFrame* frame,
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000185 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,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000203 content::MediaStreamRequestResult result);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100204
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000205 UserMediaRequestInfo* FindUserMediaRequestInfo(int request_id);
206 UserMediaRequestInfo* FindUserMediaRequestInfo(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000207 const blink::WebUserMediaRequest& request);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000208 void DeleteUserMediaRequestInfo(UserMediaRequestInfo* request);
209
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100210 MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(int request_id);
211 MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(
212 const blink::WebMediaDevicesRequest& request);
213 void DeleteMediaDevicesRequestInfo(MediaDevicesRequestInfo* request);
214
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100215 // Returns the source that use a device with |device.session_id|
216 // and |device.device.id|. NULL if such source doesn't exist.
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000217 const blink::WebMediaStreamSource* FindLocalSource(
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100218 const StreamDeviceInfo& device) const;
219
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000220 void StopLocalSource(const blink::WebMediaStreamSource& source,
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100221 bool notify_dispatcher);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100222
Torne (Richard Coles)cedac222014-06-03 10:58:34 +0100223 // Weak ref to a PeerConnectionDependencyFactory, owned by the RenderThread.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000224 // It's valid for the lifetime of RenderThread.
Torne (Richard Coles)cedac222014-06-03 10:58:34 +0100225 // TODO(xians): Remove this dependency once audio do not need it for local
226 // audio.
227 PeerConnectionDependencyFactory* dependency_factory_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000228
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
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100233 LocalStreamSources local_sources_;
234
Ben Murdoch0529e5d2014-04-24 10:50:13 +0100235 UserMediaRequests user_media_requests_;
236
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100237 // Requests to enumerate media devices.
238 MediaDevicesRequests media_devices_requests_;
239
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000240 DISALLOW_COPY_AND_ASSIGN(MediaStreamImpl);
241};
242
243} // namespace content
244
245#endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_