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_PUBLIC_COMMON_MEDIA_STREAM_REQUEST_H_
6#define CONTENT_PUBLIC_COMMON_MEDIA_STREAM_REQUEST_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/callback_forward.h"
14#include "base/memory/scoped_ptr.h"
15#include "content/common/content_export.h"
16#include "ui/gfx/native_widget_types.h"
17#include "url/gurl.h"
18
19namespace content {
20
21// Types of media streams.
22enum MediaStreamType {
23  MEDIA_NO_SERVICE = 0,
24
25  // A device provided by the operating system (e.g., webcam input).
26  MEDIA_DEVICE_AUDIO_CAPTURE,
27  MEDIA_DEVICE_VIDEO_CAPTURE,
28
29  // Mirroring of a browser tab.
30  MEDIA_TAB_AUDIO_CAPTURE,
31  MEDIA_TAB_VIDEO_CAPTURE,
32
33  // Desktop media sources.
34  MEDIA_DESKTOP_VIDEO_CAPTURE,
35
36  // Capture system audio (post-mix loopback stream).
37  //
38  // TODO(sergeyu): Replace with MEDIA_DESKTOP_AUDIO_CAPTURE.
39  MEDIA_LOOPBACK_AUDIO_CAPTURE,
40
41  // This is used for enumerating audio output devices.
42  // TODO(grunell): Output isn't really a part of media streams. Device
43  // enumeration should be decoupled from media streams and related code.
44  MEDIA_DEVICE_AUDIO_OUTPUT,
45
46  NUM_MEDIA_TYPES
47};
48
49// Types of media stream requests that can be made to the media controller.
50enum MediaStreamRequestType {
51  MEDIA_DEVICE_ACCESS = 0,
52  MEDIA_GENERATE_STREAM,
53  MEDIA_ENUMERATE_DEVICES,
54  MEDIA_OPEN_DEVICE  // Only used in requests made by Pepper.
55};
56
57// Facing mode for video capture.
58enum VideoFacingMode {
59  MEDIA_VIDEO_FACING_NONE = 0,
60  MEDIA_VIDEO_FACING_USER,
61  MEDIA_VIDEO_FACING_ENVIRONMENT,
62  MEDIA_VIDEO_FACING_LEFT,
63  MEDIA_VIDEO_FACING_RIGHT,
64
65  NUM_MEDIA_VIDEO_FACING_MODE
66};
67
68// Elements in this enum should not be deleted or rearranged; the only
69// permitted operation is to add new elements before NUM_MEDIA_REQUEST_RESULTS.
70enum MediaStreamRequestResult {
71  MEDIA_DEVICE_OK = 0,
72  MEDIA_DEVICE_PERMISSION_DENIED = 1,
73  MEDIA_DEVICE_PERMISSION_DISMISSED = 2,
74  MEDIA_DEVICE_INVALID_STATE = 3,
75  MEDIA_DEVICE_NO_HARDWARE = 4,
76  MEDIA_DEVICE_INVALID_SECURITY_ORIGIN = 5,
77  MEDIA_DEVICE_TAB_CAPTURE_FAILURE = 6,
78  MEDIA_DEVICE_SCREEN_CAPTURE_FAILURE = 7,
79  MEDIA_DEVICE_CAPTURE_FAILURE = 8,
80  MEDIA_DEVICE_CONSTRAINT_NOT_SATISFIED = 9,
81  MEDIA_DEVICE_TRACK_START_FAILURE = 10,
82  MEDIA_DEVICE_NOT_SUPPORTED = 11,
83  MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN = 12,
84  NUM_MEDIA_REQUEST_RESULTS
85};
86
87// Convenience predicates to determine whether the given type represents some
88// audio or some video device.
89CONTENT_EXPORT bool IsAudioInputMediaType(MediaStreamType type);
90CONTENT_EXPORT bool IsVideoMediaType(MediaStreamType type);
91
92// TODO(xians): Change the structs to classes.
93// Represents one device in a request for media stream(s).
94struct CONTENT_EXPORT MediaStreamDevice {
95  MediaStreamDevice();
96
97  MediaStreamDevice(
98      MediaStreamType type,
99      const std::string& id,
100      const std::string& name);
101
102  MediaStreamDevice(
103      MediaStreamType type,
104      const std::string& id,
105      const std::string& name,
106      int sample_rate,
107      int channel_layout,
108      int frames_per_buffer);
109
110  ~MediaStreamDevice();
111
112  bool IsEqual(const MediaStreamDevice& second) const;
113
114  // The device's type.
115  MediaStreamType type;
116
117  // The device's unique ID.
118  std::string id;
119
120  // The facing mode for video capture device.
121  VideoFacingMode video_facing;
122
123  // The device id of a matched output device if any (otherwise empty).
124  // Only applicable to audio devices.
125  std::string matched_output_device_id;
126
127  // The device's "friendly" name. Not guaranteed to be unique.
128  std::string name;
129
130  // Contains properties that match directly with those with the same name
131  // in media::AudioParameters.
132  struct AudioDeviceParameters {
133    AudioDeviceParameters()
134        : sample_rate(), channel_layout(), frames_per_buffer(), effects() {
135    }
136
137    AudioDeviceParameters(int sample_rate, int channel_layout,
138        int frames_per_buffer)
139        : sample_rate(sample_rate),
140          channel_layout(channel_layout),
141          frames_per_buffer(frames_per_buffer),
142          effects() {
143    }
144
145    // Preferred sample rate in samples per second for the device.
146    int sample_rate;
147
148    // Preferred channel configuration for the device.
149    // TODO(henrika): ideally, we would like to use media::ChannelLayout here
150    // but including media/base/channel_layout.h violates checkdeps rules.
151    int channel_layout;
152
153    // Preferred number of frames per buffer for the device.  This is filled
154    // in on the browser side and can be used by the renderer to match the
155    // expected browser side settings and avoid unnecessary buffering.
156    // See media::AudioParameters for more.
157    int frames_per_buffer;
158
159    // See media::AudioParameters::PlatformEffectsMask.
160    int effects;
161  };
162
163  // These below two member variables are valid only when the type of device is
164  // audio (i.e. IsAudioInputMediaType returns true).
165
166  // Contains the device properties of the capture device.
167  AudioDeviceParameters input;
168
169  // If the capture device has an associated output device (e.g. headphones),
170  // this will contain the properties for the output device.  If no such device
171  // exists (e.g. webcam w/mic), then the value of this member will be all
172  // zeros.
173  AudioDeviceParameters matched_output;
174};
175
176class CONTENT_EXPORT MediaStreamDevices
177    : public std::vector<MediaStreamDevice> {
178 public:
179  MediaStreamDevices();
180  MediaStreamDevices(size_t count, const MediaStreamDevice& value);
181
182  // Looks for a MediaStreamDevice based on its ID.
183  // Returns NULL if not found.
184  const MediaStreamDevice* FindById(const std::string& device_id) const;
185};
186
187typedef std::map<MediaStreamType, MediaStreamDevices> MediaStreamDeviceMap;
188
189// Represents a request for media streams (audio/video).
190// TODO(vrk): Decouple MediaStreamDevice from this header file so that
191// media_stream_options.h no longer depends on this file.
192// TODO(vrk,justinlin,wjia): Figure out a way to share this code cleanly between
193// vanilla WebRTC, Tab Capture, and Pepper Video Capture. Right now there is
194// Tab-only stuff and Pepper-only stuff being passed around to all clients,
195// which is icky.
196struct CONTENT_EXPORT MediaStreamRequest {
197  MediaStreamRequest(
198      int render_process_id,
199      int render_frame_id,
200      int page_request_id,
201      const GURL& security_origin,
202      bool user_gesture,
203      MediaStreamRequestType request_type,
204      const std::string& requested_audio_device_id,
205      const std::string& requested_video_device_id,
206      MediaStreamType audio_type,
207      MediaStreamType video_type);
208
209  ~MediaStreamRequest();
210
211  // This is the render process id for the renderer associated with generating
212  // frames for a MediaStream. Any indicators associated with a capture will be
213  // displayed for this renderer.
214  int render_process_id;
215
216  // This is the render frame id for the renderer associated with generating
217  // frames for a MediaStream. Any indicators associated with a capture will be
218  // displayed for this renderer.
219  int render_frame_id;
220
221  // The unique id combined with render_process_id and render_frame_id for
222  // identifying this request. This is used for cancelling request.
223  int page_request_id;
224
225  // Used by tab capture.
226  std::string tab_capture_device_id;
227
228  // The WebKit security origin for the current request (e.g. "html5rocks.com").
229  GURL security_origin;
230
231  // Set to true if the call was made in the context of a user gesture.
232  bool user_gesture;
233
234  // Stores the type of request that was made to the media controller. Right now
235  // this is only used to distinguish between WebRTC and Pepper requests, as the
236  // latter should not be subject to user approval but only to policy check.
237  // Pepper requests are signified by the |MEDIA_OPEN_DEVICE| value.
238  MediaStreamRequestType request_type;
239
240  // Stores the requested raw device id for physical audio or video devices.
241  std::string requested_audio_device_id;
242  std::string requested_video_device_id;
243
244  // Flag to indicate if the request contains audio.
245  MediaStreamType audio_type;
246
247  // Flag to indicate if the request contains video.
248  MediaStreamType video_type;
249};
250
251// Interface used by the content layer to notify chrome about changes in the
252// state of a media stream. Instances of this class are passed to content layer
253// when MediaStream access is approved using MediaResponseCallback.
254class MediaStreamUI {
255 public:
256  virtual ~MediaStreamUI() {}
257
258  // Called when MediaStream capturing is started. Chrome layer can call |stop|
259  // to stop the stream. Returns the platform-dependent window ID for the UI, or
260  // 0 if not applicable.
261  virtual gfx::NativeViewId OnStarted(const base::Closure& stop) = 0;
262};
263
264// Callback used return results of media access requests.
265typedef base::Callback<void(
266    const MediaStreamDevices& devices,
267    content::MediaStreamRequestResult result,
268    scoped_ptr<MediaStreamUI> ui)> MediaResponseCallback;
269
270}  // namespace content
271
272#endif  // CONTENT_PUBLIC_COMMON_MEDIA_STREAM_REQUEST_H_
273