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 "chrome/browser/media/media_capture_devices_dispatcher.h" | 5 #include "chrome/browser/media/media_capture_devices_dispatcher.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 10 #include "base/sha1.h" | 10 #include "base/sha1.h" |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 13 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" | 13 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" |
| 14 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry_factory .h" | 14 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry_factory .h" |
| 15 #include "chrome/browser/media/audio_stream_indicator.h" | 15 #include "chrome/browser/media/audio_stream_indicator.h" |
| 16 #include "chrome/browser/media/media_stream_capture_indicator.h" | 16 #include "chrome/browser/media/media_stream_capture_indicator.h" |
| 17 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 17 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/ui/media_stream_infobar_delegate.h" | 19 #include "chrome/browser/ui/media_stream_infobar_delegate.h" |
| 20 #include "chrome/browser/ui/simple_message_box.h" | 20 #include "chrome/browser/ui/simple_message_box.h" |
| 21 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
| 22 #include "chrome/common/extensions/extension.h" | 22 #include "chrome/common/extensions/extension.h" |
| 23 #include "chrome/common/extensions/feature_switch.h" | 23 #include "chrome/common/extensions/feature_switch.h" |
| 24 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
| 25 #include "components/user_prefs/pref_registry_syncable.h" | 25 #include "components/user_prefs/pref_registry_syncable.h" |
| 26 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
| 27 #include "content/public/browser/media_devices_monitor.h" | 27 #include "content/public/browser/media_devices_monitor.h" |
| 28 #include "content/public/browser/notification_service.h" | |
| 29 #include "content/public/browser/notification_source.h" | |
| 30 #include "content/public/browser/notification_types.h" | |
| 28 #include "content/public/browser/web_contents.h" | 31 #include "content/public/browser/web_contents.h" |
| 29 #include "content/public/common/media_stream_request.h" | 32 #include "content/public/common/media_stream_request.h" |
| 30 #include "extensions/common/constants.h" | 33 #include "extensions/common/constants.h" |
| 31 #include "grit/generated_resources.h" | 34 #include "grit/generated_resources.h" |
| 32 #include "ui/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
| 33 | 36 |
| 34 using content::BrowserThread; | 37 using content::BrowserThread; |
| 35 using content::MediaStreamDevices; | 38 using content::MediaStreamDevices; |
| 36 | 39 |
| 37 namespace { | 40 namespace { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 return | 76 return |
| 74 hexencoded_origin_hash == "3C2705BC432E7C51CA8553FDC5BEE873FF2468EE" || | 77 hexencoded_origin_hash == "3C2705BC432E7C51CA8553FDC5BEE873FF2468EE" || |
| 75 hexencoded_origin_hash == "50F02B8A668CAB274527D58356F07C2143080FCC"; | 78 hexencoded_origin_hash == "50F02B8A668CAB274527D58356F07C2143080FCC"; |
| 76 #else | 79 #else |
| 77 return false; | 80 return false; |
| 78 #endif | 81 #endif |
| 79 } | 82 } |
| 80 | 83 |
| 81 } // namespace | 84 } // namespace |
| 82 | 85 |
| 86 MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest( | |
| 87 content::MediaStreamRequest request, | |
| 88 content::MediaResponseCallback callback) | |
| 89 : request(request), | |
| 90 callback(callback) { | |
| 91 } | |
| 92 | |
| 93 MediaCaptureDevicesDispatcher::PendingAccessRequest::~PendingAccessRequest() {} | |
| 94 | |
| 83 MediaCaptureDevicesDispatcher* MediaCaptureDevicesDispatcher::GetInstance() { | 95 MediaCaptureDevicesDispatcher* MediaCaptureDevicesDispatcher::GetInstance() { |
| 84 return Singleton<MediaCaptureDevicesDispatcher>::get(); | 96 return Singleton<MediaCaptureDevicesDispatcher>::get(); |
| 85 } | 97 } |
| 86 | 98 |
| 87 MediaCaptureDevicesDispatcher::MediaCaptureDevicesDispatcher() | 99 MediaCaptureDevicesDispatcher::MediaCaptureDevicesDispatcher() |
| 88 : devices_enumerated_(false), | 100 : devices_enumerated_(false), |
| 89 media_stream_capture_indicator_(new MediaStreamCaptureIndicator()), | 101 media_stream_capture_indicator_(new MediaStreamCaptureIndicator()), |
| 90 audio_stream_indicator_(new AudioStreamIndicator()) {} | 102 audio_stream_indicator_(new AudioStreamIndicator()) { |
| 103 notifications_registrar_.Add( | |
| 104 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | |
| 105 content::NotificationService::AllSources()); | |
| 106 } | |
| 91 | 107 |
| 92 MediaCaptureDevicesDispatcher::~MediaCaptureDevicesDispatcher() {} | 108 MediaCaptureDevicesDispatcher::~MediaCaptureDevicesDispatcher() {} |
| 93 | 109 |
| 94 void MediaCaptureDevicesDispatcher::RegisterUserPrefs( | 110 void MediaCaptureDevicesDispatcher::RegisterUserPrefs( |
| 95 PrefRegistrySyncable* registry) { | 111 PrefRegistrySyncable* registry) { |
| 96 registry->RegisterStringPref(prefs::kDefaultAudioCaptureDevice, | 112 registry->RegisterStringPref(prefs::kDefaultAudioCaptureDevice, |
| 97 std::string(), | 113 std::string(), |
| 98 PrefRegistrySyncable::UNSYNCABLE_PREF); | 114 PrefRegistrySyncable::UNSYNCABLE_PREF); |
| 99 registry->RegisterStringPref(prefs::kDefaultVideoCaptureDevice, | 115 registry->RegisterStringPref(prefs::kDefaultVideoCaptureDevice, |
| 100 std::string(), | 116 std::string(), |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 130 if (!devices_enumerated_) { | 146 if (!devices_enumerated_) { |
| 131 BrowserThread::PostTask( | 147 BrowserThread::PostTask( |
| 132 BrowserThread::IO, FROM_HERE, | 148 BrowserThread::IO, FROM_HERE, |
| 133 base::Bind(&content::EnsureMonitorCaptureDevices)); | 149 base::Bind(&content::EnsureMonitorCaptureDevices)); |
| 134 devices_enumerated_ = true; | 150 devices_enumerated_ = true; |
| 135 } | 151 } |
| 136 return video_devices_; | 152 return video_devices_; |
| 137 } | 153 } |
| 138 | 154 |
| 155 void MediaCaptureDevicesDispatcher::Observe( | |
| 156 int type, | |
| 157 const content::NotificationSource& source, | |
| 158 const content::NotificationDetails& details) { | |
| 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 160 if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { | |
| 161 content::WebContents* web_contents = | |
| 162 content::Source<content::WebContents>(source).ptr(); | |
| 163 pending_requests_.erase(web_contents); | |
| 164 } | |
| 165 } | |
| 166 | |
| 139 void MediaCaptureDevicesDispatcher::ProcessMediaAccessRequest( | 167 void MediaCaptureDevicesDispatcher::ProcessMediaAccessRequest( |
| 140 content::WebContents* web_contents, | 168 content::WebContents* web_contents, |
| 141 const content::MediaStreamRequest& request, | 169 const content::MediaStreamRequest& request, |
| 142 const content::MediaResponseCallback& callback, | 170 const content::MediaResponseCallback& callback, |
| 143 const extensions::Extension* extension) { | 171 const extensions::Extension* extension) { |
| 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 145 | 173 |
| 146 if (request.video_type == content::MEDIA_SCREEN_VIDEO_CAPTURE) { | 174 if (request.video_type == content::MEDIA_SCREEN_VIDEO_CAPTURE) { |
| 147 ProcessScreenCaptureAccessRequest(web_contents, request, callback); | 175 ProcessScreenCaptureAccessRequest(web_contents, request, callback); |
| 148 } else if (extension) { | 176 } else if (extension) { |
| 149 // For extensions access is approved based on extension permissions. | 177 // For extensions access is approved based on extension permissions. |
| 150 ProcessMediaAccessRequestFromExtension( | 178 ProcessMediaAccessRequestFromExtension( |
| 151 web_contents, request, callback, extension); | 179 web_contents, request, callback, extension); |
| 152 } else { | 180 } else { |
| 153 // For all regular media requests show infobar. | 181 ProcessRegularMediaAccessRequest(web_contents, request, callback); |
| 154 MediaStreamInfoBarDelegate::Create(web_contents, request, callback); | |
| 155 } | 182 } |
| 156 } | 183 } |
| 157 | 184 |
| 158 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( | 185 void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest( |
| 159 content::WebContents* web_contents, | 186 content::WebContents* web_contents, |
| 160 const content::MediaStreamRequest& request, | 187 const content::MediaStreamRequest& request, |
| 161 const content::MediaResponseCallback& callback) { | 188 const content::MediaResponseCallback& callback) { |
| 162 content::MediaStreamDevices devices; | 189 content::MediaStreamDevices devices; |
| 163 | 190 |
| 164 bool screen_capture_enabled = | 191 bool screen_capture_enabled = |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 } | 272 } |
| 246 | 273 |
| 247 scoped_ptr<content::MediaStreamUI> ui; | 274 scoped_ptr<content::MediaStreamUI> ui; |
| 248 if (!devices.empty()) { | 275 if (!devices.empty()) { |
| 249 ui = media_stream_capture_indicator_->RegisterMediaStream( | 276 ui = media_stream_capture_indicator_->RegisterMediaStream( |
| 250 web_contents, devices); | 277 web_contents, devices); |
| 251 } | 278 } |
| 252 callback.Run(devices, ui.Pass()); | 279 callback.Run(devices, ui.Pass()); |
| 253 } | 280 } |
| 254 | 281 |
| 282 void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest( | |
| 283 content::WebContents* web_contents, | |
| 284 const content::MediaStreamRequest& request, | |
| 285 const content::MediaResponseCallback& callback) { | |
| 286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 287 | |
| 288 RequestsQueue& queue(pending_requests_[web_contents]); | |
|
tommi (sloooow) - chröme
2013/04/22 13:22:39
nit: since this is a reference use assignment. As
Sergey Ulanov
2013/04/23 05:21:44
Done.
| |
| 289 queue.push(PendingAccessRequest(request, callback)); | |
| 290 | |
| 291 // If this is the only request then show the infobar. | |
| 292 if (queue.size() == 1) | |
| 293 ProcessQueuedAccessRequest(web_contents, queue.front()); | |
| 294 } | |
| 295 | |
| 296 void MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest( | |
| 297 content::WebContents* web_contents, | |
| 298 PendingAccessRequest& request) { | |
| 299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 300 | |
| 301 MediaStreamInfoBarDelegate::Create( | |
| 302 web_contents, request.request, | |
| 303 base::Bind(&MediaCaptureDevicesDispatcher::OnAccessRequestResponse, | |
| 304 base::Unretained(this), web_contents)); | |
| 305 } | |
| 306 | |
| 307 void MediaCaptureDevicesDispatcher::OnAccessRequestResponse( | |
| 308 content::WebContents* web_contents, | |
| 309 const content::MediaStreamDevices& devices, | |
| 310 scoped_ptr<content::MediaStreamUI> ui) { | |
| 311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 312 | |
| 313 std::map<content::WebContents*, RequestsQueue>::iterator it = | |
| 314 pending_requests_.find(web_contents); | |
| 315 DCHECK(it != pending_requests_.end()); | |
| 316 RequestsQueue& queue(it->second); | |
| 317 content::MediaResponseCallback callback = queue.front().callback; | |
| 318 queue.pop(); | |
| 319 if (!queue.empty()) | |
| 320 ProcessQueuedAccessRequest(web_contents, queue.front()); | |
| 321 | |
| 322 callback.Run(devices, ui.Pass()); | |
| 323 } | |
| 324 | |
| 255 void MediaCaptureDevicesDispatcher::GetDefaultDevicesForProfile( | 325 void MediaCaptureDevicesDispatcher::GetDefaultDevicesForProfile( |
| 256 Profile* profile, | 326 Profile* profile, |
| 257 bool audio, | 327 bool audio, |
| 258 bool video, | 328 bool video, |
| 259 content::MediaStreamDevices* devices) { | 329 content::MediaStreamDevices* devices) { |
| 260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 261 DCHECK(audio || video); | 331 DCHECK(audio || video); |
| 262 | 332 |
| 263 PrefService* prefs = profile->GetPrefs(); | 333 PrefService* prefs = profile->GetPrefs(); |
| 264 std::string default_device; | 334 std::string default_device; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 int render_process_id, | 441 int render_process_id, |
| 372 int render_view_id, | 442 int render_view_id, |
| 373 const content::MediaStreamDevice& device, | 443 const content::MediaStreamDevice& device, |
| 374 content::MediaRequestState state) { | 444 content::MediaRequestState state) { |
| 375 FOR_EACH_OBSERVER(Observer, observers_, | 445 FOR_EACH_OBSERVER(Observer, observers_, |
| 376 OnRequestUpdate(render_process_id, | 446 OnRequestUpdate(render_process_id, |
| 377 render_view_id, | 447 render_view_id, |
| 378 device, | 448 device, |
| 379 state)); | 449 state)); |
| 380 } | 450 } |
| OLD | NEW |