Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/extensions/api/webrtc_audio_private/webrtc_audio_privat e_api.h" | 5 #include "chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_privat e_api.h" |
| 6 | 6 |
| 7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/task_runner_util.h" | 9 #include "base/task_runner_util.h" |
| 10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" | 10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
| 11 #include "chrome/browser/extensions/extension_tab_util.h" | 11 #include "chrome/browser/extensions/extension_tab_util.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "content/public/browser/media_device_id.h" | 13 #include "content/public/browser/media_device_id.h" |
| 14 #include "content/public/browser/resource_context.h" | 14 #include "content/public/browser/resource_context.h" |
| 15 #include "content/public/browser/web_contents.h" | 15 #include "content/public/browser/web_contents.h" |
| 16 #include "extensions/browser/event_router.h" | 16 #include "extensions/browser/event_router.h" |
| 17 #include "extensions/browser/extension_registry.h" | 17 #include "extensions/browser/extension_registry.h" |
| 18 #include "extensions/common/error_utils.h" | 18 #include "extensions/common/error_utils.h" |
| 19 #include "extensions/common/permissions/permissions_data.h" | 19 #include "extensions/common/permissions/permissions_data.h" |
| 20 #include "media/audio/audio_manager_base.h" | 20 #include "media/audio/audio_manager_base.h" |
| 21 #include "media/audio/audio_output_controller.h" | 21 #include "media/audio/audio_output_controller.h" |
| 22 | 22 |
| 23 namespace extensions { | 23 namespace extensions { |
| 24 | 24 |
| 25 using content::BrowserThread; | 25 using content::BrowserThread; |
| 26 using content::RenderViewHost; | 26 using content::RenderProcessHost; |
| 27 using media::AudioDeviceNames; | 27 using media::AudioDeviceNames; |
| 28 using media::AudioManager; | 28 using media::AudioManager; |
| 29 | 29 |
| 30 namespace wap = api::webrtc_audio_private; | 30 namespace wap = api::webrtc_audio_private; |
| 31 | 31 |
| 32 using api::webrtc_audio_private::RequestInfo; | |
| 33 | |
| 32 static base::LazyInstance< | 34 static base::LazyInstance< |
| 33 BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService> > g_factory = | 35 BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService> > g_factory = |
| 34 LAZY_INSTANCE_INITIALIZER; | 36 LAZY_INSTANCE_INITIALIZER; |
| 35 | 37 |
| 36 WebrtcAudioPrivateEventService::WebrtcAudioPrivateEventService( | 38 WebrtcAudioPrivateEventService::WebrtcAudioPrivateEventService( |
| 37 content::BrowserContext* context) | 39 content::BrowserContext* context) |
| 38 : browser_context_(context) { | 40 : browser_context_(context) { |
| 39 // In unit tests, the SystemMonitor may not be created. | 41 // In unit tests, the SystemMonitor may not be created. |
| 40 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); | 42 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); |
| 41 if (system_monitor) | 43 if (system_monitor) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 base::Bind(&WebrtcAudioPrivateFunction::OnOutputDeviceNames, | 125 base::Bind(&WebrtcAudioPrivateFunction::OnOutputDeviceNames, |
| 124 this, | 126 this, |
| 125 Passed(&device_names))); | 127 Passed(&device_names))); |
| 126 } | 128 } |
| 127 | 129 |
| 128 void WebrtcAudioPrivateFunction::OnOutputDeviceNames( | 130 void WebrtcAudioPrivateFunction::OnOutputDeviceNames( |
| 129 scoped_ptr<AudioDeviceNames> device_names) { | 131 scoped_ptr<AudioDeviceNames> device_names) { |
| 130 NOTREACHED(); | 132 NOTREACHED(); |
| 131 } | 133 } |
| 132 | 134 |
| 133 bool WebrtcAudioPrivateFunction::GetControllerList(int tab_id) { | 135 bool WebrtcAudioPrivateFunction::GetControllerList(const RequestInfo& request) { |
| 134 content::WebContents* contents = NULL; | 136 content::RenderProcessHost* rhp = NULL; |
|
tommi (sloooow) - chröme
2015/01/30 20:17:39
nit: rph
(also, should we use nullptr?)
| |
| 135 if (!ExtensionTabUtil::GetTabById( | 137 |
| 136 tab_id, GetProfile(), true, NULL, NULL, &contents, NULL)) { | 138 // If |guest_process_id| is defined, directly use this id to find the |
| 137 error_ = extensions::ErrorUtils::FormatErrorMessage( | 139 // corresponding RenderProcessHost. |
| 138 extensions::tabs_constants::kTabNotFoundError, | 140 if (request.guest_process_id.get()) { |
| 139 base::IntToString(tab_id)); | 141 rhp = content::RenderProcessHost::FromID(*request.guest_process_id.get()); |
| 142 } else if (request.tab_id.get()) { | |
| 143 int tab_id = *request.tab_id.get(); | |
| 144 content::WebContents* contents = NULL; | |
| 145 if (!ExtensionTabUtil::GetTabById(tab_id, GetProfile(), true, NULL, NULL, | |
| 146 &contents, NULL)) { | |
| 147 error_ = extensions::ErrorUtils::FormatErrorMessage( | |
| 148 extensions::tabs_constants::kTabNotFoundError, | |
| 149 base::IntToString(tab_id)); | |
| 150 return false; | |
| 151 } | |
| 152 rhp = contents->GetRenderProcessHost(); | |
| 153 } else { | |
| 140 return false; | 154 return false; |
| 141 } | 155 } |
| 142 | 156 |
| 143 RenderViewHost* rvh = contents->GetRenderViewHost(); | 157 if (!rhp) |
| 144 if (!rvh) | |
| 145 return false; | 158 return false; |
| 146 | 159 |
| 147 rvh->GetAudioOutputControllers(base::Bind( | 160 rhp->GetAudioOutputControllers( |
| 148 &WebrtcAudioPrivateFunction::OnControllerList, this)); | 161 base::Bind(&WebrtcAudioPrivateFunction::OnControllerList, this)); |
| 149 return true; | 162 return true; |
| 150 } | 163 } |
| 151 | 164 |
| 152 void WebrtcAudioPrivateFunction::OnControllerList( | 165 void WebrtcAudioPrivateFunction::OnControllerList( |
| 153 const content::RenderViewHost::AudioOutputControllerList& list) { | 166 const content::RenderProcessHost::AudioOutputControllerList& list) { |
| 154 NOTREACHED(); | 167 NOTREACHED(); |
| 155 } | 168 } |
| 156 | 169 |
| 157 void WebrtcAudioPrivateFunction::CalculateHMAC(const std::string& raw_id) { | 170 void WebrtcAudioPrivateFunction::CalculateHMAC(const std::string& raw_id) { |
| 158 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 171 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 159 BrowserThread::PostTask( | 172 BrowserThread::PostTask( |
| 160 BrowserThread::IO, | 173 BrowserThread::IO, |
| 161 FROM_HERE, | 174 FROM_HERE, |
| 162 base::Bind(&WebrtcAudioPrivateFunction::CalculateHMAC, this, raw_id)); | 175 base::Bind(&WebrtcAudioPrivateFunction::CalculateHMAC, this, raw_id)); |
| 163 return; | 176 return; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 } | 260 } |
| 248 | 261 |
| 249 bool WebrtcAudioPrivateGetActiveSinkFunction::RunAsync() { | 262 bool WebrtcAudioPrivateGetActiveSinkFunction::RunAsync() { |
| 250 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 263 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 251 InitResourceContext(); | 264 InitResourceContext(); |
| 252 | 265 |
| 253 scoped_ptr<wap::GetActiveSink::Params> params( | 266 scoped_ptr<wap::GetActiveSink::Params> params( |
| 254 wap::GetActiveSink::Params::Create(*args_)); | 267 wap::GetActiveSink::Params::Create(*args_)); |
| 255 EXTENSION_FUNCTION_VALIDATE(params.get()); | 268 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 256 | 269 |
| 257 return GetControllerList(params->tab_id); | 270 return GetControllerList(params->request); |
| 258 } | 271 } |
| 259 | 272 |
| 260 void WebrtcAudioPrivateGetActiveSinkFunction::OnControllerList( | 273 void WebrtcAudioPrivateGetActiveSinkFunction::OnControllerList( |
| 261 const RenderViewHost::AudioOutputControllerList& controllers) { | 274 const RenderProcessHost::AudioOutputControllerList& controllers) { |
| 262 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 275 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 263 | 276 |
| 264 if (controllers.empty()) { | 277 if (controllers.empty()) { |
| 265 // If there is no current audio stream for the rvh, we return an | 278 // If there is no current audio stream for the rvh, we return an |
| 266 // empty string as the sink ID. | 279 // empty string as the sink ID. |
| 267 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: No controllers."; | 280 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: No controllers."; |
| 268 results_.reset( | 281 results_.reset( |
| 269 wap::GetActiveSink::Results::Create(std::string()).release()); | 282 wap::GetActiveSink::Results::Create(std::string()).release()); |
| 270 SendResponse(true); | 283 SendResponse(true); |
| 271 } else { | 284 } else { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 288 std::string result = hmac_id; | 301 std::string result = hmac_id; |
| 289 if (result.empty()) { | 302 if (result.empty()) { |
| 290 DVLOG(2) << "Received empty ID, replacing with default ID."; | 303 DVLOG(2) << "Received empty ID, replacing with default ID."; |
| 291 result = media::AudioManagerBase::kDefaultDeviceId; | 304 result = media::AudioManagerBase::kDefaultDeviceId; |
| 292 } | 305 } |
| 293 results_.reset(wap::GetActiveSink::Results::Create(result).release()); | 306 results_.reset(wap::GetActiveSink::Results::Create(result).release()); |
| 294 SendResponse(true); | 307 SendResponse(true); |
| 295 } | 308 } |
| 296 | 309 |
| 297 WebrtcAudioPrivateSetActiveSinkFunction:: | 310 WebrtcAudioPrivateSetActiveSinkFunction:: |
| 298 WebrtcAudioPrivateSetActiveSinkFunction() | 311 WebrtcAudioPrivateSetActiveSinkFunction() |
| 299 : tab_id_(0), | 312 : num_remaining_sink_ids_(0) { |
| 300 num_remaining_sink_ids_(0) { | |
| 301 } | 313 } |
| 302 | 314 |
| 303 WebrtcAudioPrivateSetActiveSinkFunction:: | 315 WebrtcAudioPrivateSetActiveSinkFunction:: |
| 304 ~WebrtcAudioPrivateSetActiveSinkFunction() { | 316 ~WebrtcAudioPrivateSetActiveSinkFunction() { |
| 305 } | 317 } |
| 306 | 318 |
| 307 bool WebrtcAudioPrivateSetActiveSinkFunction::RunAsync() { | 319 bool WebrtcAudioPrivateSetActiveSinkFunction::RunAsync() { |
| 308 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 320 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 309 scoped_ptr<wap::SetActiveSink::Params> params( | 321 scoped_ptr<wap::SetActiveSink::Params> params( |
| 310 wap::SetActiveSink::Params::Create(*args_)); | 322 wap::SetActiveSink::Params::Create(*args_)); |
| 311 EXTENSION_FUNCTION_VALIDATE(params.get()); | 323 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 312 | 324 |
| 313 InitResourceContext(); | 325 InitResourceContext(); |
| 314 | 326 |
| 315 tab_id_ = params->tab_id; | 327 if (params->request.guest_process_id.get()) { |
| 328 request_info_.guest_process_id.reset( | |
| 329 new int(*params->request.guest_process_id.get())); | |
| 330 } else if (params->request.tab_id.get()) { | |
| 331 request_info_.tab_id.reset(new int(*params->request.tab_id.get())); | |
| 332 } else { | |
| 333 return false; | |
| 334 } | |
| 335 | |
| 316 sink_id_ = params->sink_id; | 336 sink_id_ = params->sink_id; |
| 317 | 337 |
| 318 return GetControllerList(tab_id_); | 338 return GetControllerList(request_info_); |
| 319 } | 339 } |
| 320 | 340 |
| 321 void WebrtcAudioPrivateSetActiveSinkFunction::OnControllerList( | 341 void WebrtcAudioPrivateSetActiveSinkFunction::OnControllerList( |
| 322 const RenderViewHost::AudioOutputControllerList& controllers) { | 342 const RenderProcessHost::AudioOutputControllerList& controllers) { |
| 323 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 343 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 324 | 344 |
| 345 std::string requested_process_type; | |
| 346 int requested_process_id; | |
| 347 if (request_info_.guest_process_id.get()) { | |
| 348 requested_process_type = "guestProcessId"; | |
| 349 requested_process_id = *request_info_.guest_process_id.get(); | |
| 350 } else { | |
| 351 requested_process_type = "tabId"; | |
| 352 requested_process_id = *request_info_.tab_id.get(); | |
| 353 } | |
| 354 | |
| 325 controllers_ = controllers; | 355 controllers_ = controllers; |
| 326 num_remaining_sink_ids_ = controllers_.size(); | 356 num_remaining_sink_ids_ = controllers_.size(); |
| 327 if (num_remaining_sink_ids_ == 0) { | 357 if (num_remaining_sink_ids_ == 0) { |
| 328 error_ = extensions::ErrorUtils::FormatErrorMessage( | 358 error_ = extensions::ErrorUtils::FormatErrorMessage( |
| 329 "No active stream for tab with id: *.", | 359 "No active stream for " + requested_process_type, |
| 330 base::IntToString(tab_id_)); | 360 base::IntToString(requested_process_id)); |
| 331 SendResponse(false); | 361 SendResponse(false); |
| 332 } else { | 362 } else { |
| 333 // We need to get the output device names, and calculate the HMAC | 363 // We need to get the output device names, and calculate the HMAC |
| 334 // for each, to find the raw ID for the ID provided to this API | 364 // for each, to find the raw ID for the ID provided to this API |
| 335 // function call. | 365 // function call. |
| 336 GetOutputDeviceNames(); | 366 GetOutputDeviceNames(); |
| 337 } | 367 } |
| 338 } | 368 } |
| 339 | 369 |
| 340 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceNames( | 370 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceNames( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 352 if (sink_id_ == CalculateHMACImpl(it->unique_id)) { | 382 if (sink_id_ == CalculateHMACImpl(it->unique_id)) { |
| 353 raw_sink_id = it->unique_id; | 383 raw_sink_id = it->unique_id; |
| 354 break; | 384 break; |
| 355 } | 385 } |
| 356 } | 386 } |
| 357 | 387 |
| 358 if (raw_sink_id.empty()) | 388 if (raw_sink_id.empty()) |
| 359 DVLOG(2) << "Found no matching raw sink ID for HMAC " << sink_id_; | 389 DVLOG(2) << "Found no matching raw sink ID for HMAC " << sink_id_; |
| 360 } | 390 } |
| 361 | 391 |
| 362 RenderViewHost::AudioOutputControllerList::const_iterator it = | 392 RenderProcessHost::AudioOutputControllerList::const_iterator it = |
| 363 controllers_.begin(); | 393 controllers_.begin(); |
| 364 for (; it != controllers_.end(); ++it) { | 394 for (; it != controllers_.end(); ++it) { |
| 365 (*it)->SwitchOutputDevice(raw_sink_id, base::Bind( | 395 (*it)->SwitchOutputDevice(raw_sink_id, base::Bind( |
| 366 &WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone, this)); | 396 &WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone, this)); |
| 367 } | 397 } |
| 368 } | 398 } |
| 369 | 399 |
| 370 void WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone() { | 400 void WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone() { |
| 371 if (--num_remaining_sink_ids_ == 0) { | 401 if (--num_remaining_sink_ids_ == 0) { |
| 372 BrowserThread::PostTask( | 402 BrowserThread::PostTask( |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 473 results_.reset(wap::GetAssociatedSink::Results::Create("").release()); | 503 results_.reset(wap::GetAssociatedSink::Results::Create("").release()); |
| 474 } else { | 504 } else { |
| 475 results_.reset( | 505 results_.reset( |
| 476 wap::GetAssociatedSink::Results::Create(associated_sink_id).release()); | 506 wap::GetAssociatedSink::Results::Create(associated_sink_id).release()); |
| 477 } | 507 } |
| 478 | 508 |
| 479 SendResponse(true); | 509 SendResponse(true); |
| 480 } | 510 } |
| 481 | 511 |
| 482 } // namespace extensions | 512 } // namespace extensions |
| OLD | NEW |