Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/media/media_stream_device_settings.h" | 5 #include "content/browser/renderer_host/media/media_stream_device_settings.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 } // namespace | 81 } // namespace |
| 82 | 82 |
| 83 namespace media_stream { | 83 namespace media_stream { |
| 84 | 84 |
| 85 typedef std::map<MediaStreamType, StreamDeviceInfoArray> DeviceMap; | 85 typedef std::map<MediaStreamType, StreamDeviceInfoArray> DeviceMap; |
| 86 | 86 |
| 87 // Device request contains all data needed to keep track of requests between the | 87 // Device request contains all data needed to keep track of requests between the |
| 88 // different calls. | 88 // different calls. |
| 89 class MediaStreamDeviceSettingsRequest : public MediaStreamRequest { | 89 struct MediaStreamDeviceSettingsRequest : public MediaStreamRequest { |
| 90 public: | 90 public: |
| 91 MediaStreamDeviceSettingsRequest( | 91 MediaStreamDeviceSettingsRequest( |
| 92 int render_pid, | 92 int render_pid, |
| 93 int render_vid, | 93 int render_vid, |
| 94 const GURL& origin, | 94 const GURL& origin, |
| 95 const StreamOptions& request_options) | 95 const StreamOptions& request_options) |
| 96 : MediaStreamRequest(render_pid, render_vid, origin), | 96 : MediaStreamRequest(render_pid, render_vid, origin), |
| 97 options(request_options), | 97 options(request_options), |
| 98 posted_task(false) {} | 98 posted_task(false) {} |
| 99 | 99 |
| 100 ~MediaStreamDeviceSettingsRequest() {} | 100 ~MediaStreamDeviceSettingsRequest() {} |
| 101 | 101 |
| 102 // Request options. | 102 // Request options. |
| 103 StreamOptions options; | 103 StreamOptions options; |
| 104 // Map containing available devices for the requested capture types. | 104 // Map containing available devices for the requested capture types. |
| 105 // Note, never call devices_full[stream_type].empty() before making sure | |
| 106 // that type of device has existed on the map, otherwise it will create an | |
| 107 // empty device entry on the map. | |
| 105 DeviceMap devices_full; | 108 DeviceMap devices_full; |
| 106 // Whether or not a task was posted to make the call to | 109 // Whether or not a task was posted to make the call to |
| 107 // RequestMediaAccessPermission, to make sure that we never post twice to it. | 110 // RequestMediaAccessPermission, to make sure that we never post twice to it. |
| 108 bool posted_task; | 111 bool posted_task; |
| 109 }; | 112 }; |
| 110 | 113 |
| 111 namespace { | 114 namespace { |
| 112 | 115 |
| 113 // Sends the request to the appropriate WebContents. | 116 // Sends the request to the appropriate WebContents. |
| 114 void DoDeviceRequest( | 117 void DoDeviceRequest(const MediaStreamDeviceSettingsRequest& request, |
| 115 const MediaStreamDeviceSettingsRequest& request, | 118 const content::MediaResponseCallback& callback) { |
| 116 const content::MediaResponseCallback& callback) { | |
| 117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 118 | 120 |
| 119 // Send the permission request to the web contents. | 121 // Send the permission request to the web contents. |
| 120 content::RenderViewHostImpl* host = | 122 content::RenderViewHostImpl* host = |
| 121 content::RenderViewHostImpl::FromID(request.render_process_id, | 123 content::RenderViewHostImpl::FromID(request.render_process_id, |
| 122 request.render_view_id); | 124 request.render_view_id); |
| 123 | 125 |
| 124 // Tab may have gone away. | 126 // Tab may have gone away. |
| 125 if (!host || !host->GetDelegate()) { | 127 if (!host || !host->GetDelegate()) { |
| 126 callback.Run(content::MediaStreamDevices()); | 128 callback.Run(content::MediaStreamDevices()); |
| 127 return; | 129 return; |
| 128 } | 130 } |
| 129 | 131 |
| 130 host->GetDelegate()->RequestMediaAccessPermission(&request, callback); | 132 host->GetDelegate()->RequestMediaAccessPermission(&request, callback); |
| 131 } | 133 } |
| 132 | 134 |
| 135 bool IsRequestReadyForView( | |
| 136 media_stream::MediaStreamDeviceSettingsRequest* request) { | |
| 137 if ((request->options.audio && request->devices_full.count( | |
| 138 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) == 0) || | |
| 139 (request->options.video && request->devices_full.count( | |
| 140 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) == 0)) | |
| 141 return false; | |
| 142 | |
| 143 // We have got all the requested devices, it is ready if it has not | |
|
perkj_chrome
2012/08/10 12:26:58
nit: already been posted
no longer working on chromium
2012/08/13 11:39:53
Done.
| |
| 144 // been posted for UI. | |
| 145 return !request->posted_task; | |
| 146 } | |
| 147 | |
| 133 } // namespace | 148 } // namespace |
| 134 | 149 |
| 135 MediaStreamDeviceSettings::MediaStreamDeviceSettings( | 150 MediaStreamDeviceSettings::MediaStreamDeviceSettings( |
| 136 SettingsRequester* requester) | 151 SettingsRequester* requester) |
| 137 : requester_(requester), | 152 : requester_(requester), |
| 138 use_fake_ui_(false), | 153 use_fake_ui_(false), |
| 139 weak_ptr_factory_(this) { | 154 weak_ptr_factory_(this) { |
| 140 DCHECK(requester_); | 155 DCHECK(requester_); |
| 141 } | 156 } |
| 142 | 157 |
| 143 MediaStreamDeviceSettings::~MediaStreamDeviceSettings() { | 158 MediaStreamDeviceSettings::~MediaStreamDeviceSettings() { |
| 144 STLDeleteValues(&requests_); | 159 STLDeleteValues(&requests_); |
| 145 } | 160 } |
| 146 | 161 |
| 147 void MediaStreamDeviceSettings::RequestCaptureDeviceUsage( | 162 void MediaStreamDeviceSettings::RequestCaptureDeviceUsage( |
| 148 const std::string& label, int render_process_id, int render_view_id, | 163 const std::string& label, int render_process_id, int render_view_id, |
| 149 const StreamOptions& request_options, const GURL& security_origin) { | 164 const StreamOptions& request_options, const GURL& security_origin) { |
| 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 151 | 166 DCHECK(requests_.find(label) == requests_.end()); |
| 152 if (requests_.find(label) != requests_.end()) { | |
| 153 // Request with this id already exists. | |
| 154 requester_->SettingsError(label); | |
| 155 return; | |
| 156 } | |
| 157 | 167 |
| 158 // Create a new request. | 168 // Create a new request. |
| 159 requests_.insert(std::make_pair(label, new MediaStreamDeviceSettingsRequest( | 169 requests_.insert(std::make_pair(label, new MediaStreamDeviceSettingsRequest( |
| 160 render_process_id, render_view_id, security_origin, request_options))); | 170 render_process_id, render_view_id, security_origin, request_options))); |
| 161 } | 171 } |
| 162 | 172 |
| 163 void MediaStreamDeviceSettings::RemovePendingCaptureRequest( | 173 void MediaStreamDeviceSettings::RemovePendingCaptureRequest( |
| 164 const std::string& label) { | 174 const std::string& label) { |
| 165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 166 | |
| 167 SettingsRequests::iterator request_it = requests_.find(label); | 176 SettingsRequests::iterator request_it = requests_.find(label); |
| 168 if (request_it != requests_.end()) { | 177 if (request_it != requests_.end()) { |
| 169 // Proceed the next pending request for the same page. | |
| 170 MediaStreamDeviceSettingsRequest* request = request_it->second; | 178 MediaStreamDeviceSettingsRequest* request = request_it->second; |
| 171 std::string new_label = FindReadyRequestForView(request->render_view_id, | 179 int render_view_id = request->render_view_id; |
| 172 request->render_process_id); | 180 int render_process_id = request->render_process_id; |
| 173 if (!new_label.empty()) { | 181 bool was_posted = request->posted_task; |
| 174 PostRequestToUi(new_label); | |
| 175 } | |
| 176 | |
| 177 // TODO(xians): Post a cancel request on UI thread to dismiss the infobar | 182 // TODO(xians): Post a cancel request on UI thread to dismiss the infobar |
| 178 // if request has been sent to the UI. | 183 // if request has been sent to the UI. |
| 179 // Remove the request from the queue. | 184 // Remove the request from the queue. |
| 180 requests_.erase(request_it); | 185 requests_.erase(request_it); |
| 181 delete request; | 186 delete request; |
| 187 | |
| 188 // Simply return if the canceled request has not been brought to UI. | |
| 189 if (!was_posted) | |
| 190 return; | |
| 191 | |
| 192 // Proceed the next pending request to replace the old infobar on the same | |
| 193 // page. | |
| 194 std::string new_label = FindReadyRequestForView(render_view_id, | |
| 195 render_process_id); | |
| 196 if (!new_label.empty()) { | |
| 197 if (use_fake_ui_) | |
| 198 PostRequestToFakeUI(new_label); | |
| 199 else | |
| 200 PostRequestToUi(new_label); | |
| 201 } | |
| 182 } | 202 } |
| 183 } | 203 } |
| 184 | 204 |
| 185 void MediaStreamDeviceSettings::AvailableDevices( | 205 void MediaStreamDeviceSettings::AvailableDevices( |
| 186 const std::string& label, | 206 const std::string& label, |
| 187 MediaStreamType stream_type, | 207 MediaStreamType stream_type, |
| 188 const StreamDeviceInfoArray& devices) { | 208 const StreamDeviceInfoArray& devices) { |
| 189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 190 | 210 |
| 191 SettingsRequests::iterator request_it = requests_.find(label); | 211 SettingsRequests::iterator request_it = requests_.find(label); |
| 192 DCHECK(request_it != requests_.end()); | 212 DCHECK(request_it != requests_.end()); |
| 193 | |
| 194 // Add the answer for the request. | 213 // Add the answer for the request. |
| 195 MediaStreamDeviceSettingsRequest* request = request_it->second; | 214 MediaStreamDeviceSettingsRequest* request = request_it->second; |
| 196 DCHECK_EQ(request->devices_full.count(stream_type), static_cast<size_t>(0)) << | 215 DCHECK_EQ(request->devices_full.count(stream_type), static_cast<size_t>(0)) |
| 197 "This request already has a list of devices for this stream type."; | 216 << "This request already has a list of devices for this stream type."; |
| 198 request->devices_full[stream_type] = devices; | 217 request->devices_full[stream_type] = devices; |
| 199 | 218 |
| 200 // Check if we're done. | 219 if (IsRequestReadyForView(request)) { |
| 201 size_t num_media_requests = 0; | 220 if (use_fake_ui_) { |
| 202 if (request->options.audio) { | 221 PostRequestToFakeUI(label); |
| 203 num_media_requests++; | 222 return; |
| 204 } | 223 } |
| 205 if (request->options.video) { | |
| 206 num_media_requests++; | |
| 207 } | |
| 208 | 224 |
| 209 if (request->devices_full.size() == num_media_requests) { | 225 // Since the UI can only handle one request at the time, verify there |
| 210 // We have all answers needed. | 226 // is no unanswered request posted for this view. If there is, this |
| 211 if (!use_fake_ui_) { | 227 // new request will be handled once we get a response for the first one. |
| 212 // Abort if the task was already posted: wait for it to PostResponse. | 228 if (IsUiBusy(request->render_view_id, request->render_process_id)) |
| 213 if (request->posted_task) { | 229 return; |
|
wjia(left Chromium)
2012/08/12 16:05:45
No need to have "return" here and above. It can be
no longer working on chromium
2012/08/13 11:39:53
Done.
| |
| 214 return; | |
| 215 } | |
| 216 // Since the UI can only handle one request at the time, verify there | |
| 217 // is no unanswered request posted for this view. If there is, this | |
| 218 // new request will be handled once we get a response for the first one. | |
| 219 if (IsUiBusy(request->render_view_id, request->render_process_id)) { | |
| 220 return; | |
| 221 } | |
| 222 PostRequestToUi(label); | |
| 223 } else { | |
| 224 // Used to fake UI, which is needed for server based testing. | |
| 225 // Choose first non-opened device for each media type. | |
| 226 StreamDeviceInfoArray devices_to_use; | |
| 227 for (DeviceMap::iterator it = request->devices_full.begin(); | |
| 228 it != request->devices_full.end(); ++it) { | |
| 229 for (StreamDeviceInfoArray::iterator device_it = it->second.begin(); | |
| 230 device_it != it->second.end(); ++device_it) { | |
| 231 if (!device_it->in_use) { | |
| 232 devices_to_use.push_back(*device_it); | |
| 233 break; | |
| 234 } | |
| 235 } | |
| 236 } | |
| 237 | 230 |
| 238 if (!request->devices_full[ | 231 PostRequestToUi(label); |
| 239 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE].empty() && | |
| 240 num_media_requests != devices_to_use.size()) { | |
| 241 // Not all requested device types were opened. This happens if all | |
| 242 // video capture devices are already opened, |in_use| isn't set for | |
| 243 // audio devices. Allow the first video capture device in the list to be | |
| 244 // opened for this user too. | |
| 245 StreamDeviceInfoArray device_array = | |
| 246 request->devices_full[ | |
| 247 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE]; | |
| 248 devices_to_use.push_back(*(device_array.begin())); | |
| 249 } | |
| 250 | |
| 251 // Post result and delete request. | |
| 252 requester_->DevicesAccepted(label, devices_to_use); | |
| 253 requests_.erase(request_it); | |
| 254 delete request; | |
| 255 } | |
| 256 } | 232 } |
| 257 } | 233 } |
| 258 | 234 |
| 259 void MediaStreamDeviceSettings::PostResponse( | 235 void MediaStreamDeviceSettings::PostResponse( |
| 260 const std::string& label, | 236 const std::string& label, |
| 261 const content::MediaStreamDevices& devices) { | 237 const content::MediaStreamDevices& devices) { |
| 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 263 | |
| 264 SettingsRequests::iterator req = requests_.find(label); | 239 SettingsRequests::iterator req = requests_.find(label); |
| 265 // Return if the request has been removed. | 240 // Return if the request has been removed. |
| 266 if (req == requests_.end()) | 241 if (req == requests_.end()) |
| 267 return; | 242 return; |
| 268 | 243 |
| 269 DCHECK(requester_); | 244 DCHECK(requester_); |
| 270 MediaStreamDeviceSettingsRequest* request = req->second; | 245 scoped_ptr<MediaStreamDeviceSettingsRequest> request(req->second); |
| 271 requests_.erase(req); | 246 requests_.erase(req); |
| 272 | 247 |
| 273 // Look for queued requests for the same view. If there is a pending request, | 248 // Look for queued requests for the same view. If there is a pending request, |
| 274 // post it for user approval. | 249 // post it for user approval. |
| 275 std::string new_label = FindReadyRequestForView(request->render_view_id, | 250 std::string new_label = FindReadyRequestForView(request->render_view_id, |
| 276 request->render_process_id); | 251 request->render_process_id); |
| 277 if (!new_label.empty()) { | 252 if (!new_label.empty()) { |
| 278 PostRequestToUi(new_label); | 253 if (use_fake_ui_) |
| 254 PostRequestToFakeUI(new_label); | |
| 255 else | |
| 256 PostRequestToUi(new_label); | |
| 279 } | 257 } |
|
wjia(left Chromium)
2012/08/12 16:05:45
This portion of code is same as in RemovePendingCa
no longer working on chromium
2012/08/13 11:39:53
Done.
| |
| 280 | 258 |
| 281 if (devices.size() > 0) { | 259 if (devices.size() > 0) { |
| 282 // Build a list of "full" device objects for the accepted devices. | 260 // Build a list of "full" device objects for the accepted devices. |
| 283 StreamDeviceInfoArray deviceList; | 261 StreamDeviceInfoArray deviceList; |
| 284 for (content::MediaStreamDevices::const_iterator dev = devices.begin(); | 262 for (content::MediaStreamDevices::const_iterator dev = devices.begin(); |
| 285 dev != devices.end(); ++dev) { | 263 dev != devices.end(); ++dev) { |
| 286 DeviceMap::iterator subList = request->devices_full.find(dev->type); | 264 DeviceMap::iterator subList = request->devices_full.find(dev->type); |
| 287 DCHECK(subList != request->devices_full.end()); | 265 DCHECK(subList != request->devices_full.end()); |
| 288 | 266 |
| 289 deviceList.push_back(*std::find_if(subList->second.begin(), | 267 deviceList.push_back(*std::find_if(subList->second.begin(), |
| 290 subList->second.end(), DeviceIdEquals(dev->device_id))); | 268 subList->second.end(), DeviceIdEquals(dev->device_id))); |
| 291 } | 269 } |
| 292 requester_->DevicesAccepted(label, deviceList); | 270 requester_->DevicesAccepted(label, deviceList); |
| 293 } else { | 271 } else { |
| 294 requester_->SettingsError(label); | 272 requester_->SettingsError(label); |
| 295 } | 273 } |
| 296 delete request; | |
| 297 } | 274 } |
| 298 | 275 |
| 299 void MediaStreamDeviceSettings::UseFakeUI() { | 276 void MediaStreamDeviceSettings::UseFakeUI() { |
| 300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 301 use_fake_ui_ = true; | 278 use_fake_ui_ = true; |
| 302 } | 279 } |
| 303 | 280 |
| 304 bool MediaStreamDeviceSettings::IsUiBusy(int render_view_id, | 281 bool MediaStreamDeviceSettings::IsUiBusy(int render_view_id, |
| 305 int render_process_id) { | 282 int render_process_id) { |
| 306 for (SettingsRequests::iterator it = requests_.begin(); | 283 for (SettingsRequests::iterator it = requests_.begin(); |
| 307 it != requests_.end(); ++it) { | 284 it != requests_.end(); ++it) { |
| 308 if (it->second->render_process_id == render_process_id && | 285 if (it->second->render_process_id == render_process_id && |
| 309 it->second->render_view_id == render_view_id && | 286 it->second->render_view_id == render_view_id && |
| 310 it->second->posted_task) { | 287 it->second->posted_task) { |
| 311 return true; | 288 return true; |
| 312 } | 289 } |
| 313 } | 290 } |
| 314 return false; | 291 return false; |
| 315 } | 292 } |
| 316 | 293 |
| 317 std::string MediaStreamDeviceSettings::FindReadyRequestForView( | 294 std::string MediaStreamDeviceSettings::FindReadyRequestForView( |
| 318 int render_view_id, int render_process_id) { | 295 int render_view_id, int render_process_id) { |
| 319 for (SettingsRequests::iterator it = requests_.begin(); it != requests_.end(); | 296 for (SettingsRequests::iterator it = requests_.begin(); it != requests_.end(); |
| 320 ++it) { | 297 ++it) { |
| 321 if (it->second->render_process_id == render_process_id && | 298 if (it->second->render_process_id == render_process_id && |
| 322 it->second->render_view_id == render_view_id) { | 299 it->second->render_view_id == render_view_id) { |
| 323 // This request belongs to the given render view. | 300 // This request belongs to the given render view. |
| 324 MediaStreamDeviceSettingsRequest* request = it->second; | 301 MediaStreamDeviceSettingsRequest* request = it->second; |
| 325 if (request->options.audio && | 302 if (IsRequestReadyForView(request)) |
| 326 request->devices_full[ | 303 return it->first; |
| 327 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE].empty()) { | |
| 328 // Audio requested, but no devices enumerated yet. Continue to next | |
| 329 // request. | |
| 330 continue; | |
| 331 } | |
| 332 if (request->options.video && | |
| 333 request->devices_full[ | |
| 334 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE].empty()) { | |
| 335 // Video requested, but no devices enumerated yet. Continue to next | |
| 336 // request. | |
| 337 continue; | |
| 338 } | |
| 339 // This request belongs to the same view as the treated request and is | |
| 340 // ready to be requested. Return its label. | |
| 341 return it->first; | |
| 342 } | 304 } |
| 343 } | 305 } |
| 344 return std::string(); | 306 return std::string(); |
| 345 } | 307 } |
| 346 | 308 |
| 347 void MediaStreamDeviceSettings::PostRequestToUi(const std::string& label) { | 309 void MediaStreamDeviceSettings::PostRequestToUi(const std::string& label) { |
| 348 MediaStreamDeviceSettingsRequest* request = requests_[label]; | 310 MediaStreamDeviceSettingsRequest* request = requests_[label]; |
| 349 DCHECK(request != NULL); | 311 DCHECK(request != NULL); |
| 350 | 312 |
| 351 request->posted_task = true; | 313 request->posted_task = true; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 365 new ResponseCallbackHelper(weak_ptr_factory_.GetWeakPtr()); | 327 new ResponseCallbackHelper(weak_ptr_factory_.GetWeakPtr()); |
| 366 content::MediaResponseCallback callback = | 328 content::MediaResponseCallback callback = |
| 367 base::Bind(&ResponseCallbackHelper::PostResponse, | 329 base::Bind(&ResponseCallbackHelper::PostResponse, |
| 368 helper.get(), label); | 330 helper.get(), label); |
| 369 | 331 |
| 370 BrowserThread::PostTask( | 332 BrowserThread::PostTask( |
| 371 BrowserThread::UI, FROM_HERE, | 333 BrowserThread::UI, FROM_HERE, |
| 372 base::Bind(&DoDeviceRequest, *request, callback)); | 334 base::Bind(&DoDeviceRequest, *request, callback)); |
| 373 } | 335 } |
| 374 | 336 |
| 337 void MediaStreamDeviceSettings::PostRequestToFakeUI(const std::string& label) { | |
| 338 SettingsRequests::iterator request_it = requests_.find(label); | |
| 339 DCHECK(request_it != requests_.end()); | |
| 340 MediaStreamDeviceSettingsRequest* request = request_it->second; | |
| 341 // Used to fake UI, which is needed for server based testing. | |
| 342 // Choose first non-opened device for each media type. | |
| 343 content::MediaStreamDevices devices_to_use; | |
| 344 for (DeviceMap::iterator it = request->devices_full.begin(); | |
| 345 it != request->devices_full.end(); ++it) { | |
| 346 StreamDeviceInfoArray::iterator device_it = it->second.begin(); | |
| 347 for (; device_it != it->second.end(); ++device_it) { | |
| 348 if (!device_it->in_use) { | |
| 349 devices_to_use.push_back(content::MediaStreamDevice( | |
| 350 device_it->stream_type, device_it->device_id, device_it->name)); | |
| 351 break; | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 if (it->second.size() != 0 && device_it == it->second.end()) { | |
| 356 // Use the first capture device in the list if all the devices are | |
| 357 // being used. | |
| 358 devices_to_use.push_back( | |
| 359 content::MediaStreamDevice(it->second.begin()->stream_type, | |
| 360 it->second.begin()->device_id, | |
| 361 it->second.begin()->name)); | |
| 362 } | |
| 363 } | |
| 364 | |
| 365 BrowserThread::PostTask( | |
| 366 BrowserThread::IO, FROM_HERE, | |
| 367 base::Bind(&MediaStreamDeviceSettings::PostResponse, | |
| 368 weak_ptr_factory_.GetWeakPtr(), label, devices_to_use)); | |
| 369 } | |
| 370 | |
| 375 } // namespace media_stream | 371 } // namespace media_stream |
| OLD | NEW |