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* rph = 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 rph = 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 rph = contents->GetRenderProcessHost(); |
| 153 } else { |
140 return false; | 154 return false; |
141 } | 155 } |
142 | 156 |
143 RenderViewHost* rvh = contents->GetRenderViewHost(); | 157 if (!rph) |
144 if (!rvh) | |
145 return false; | 158 return false; |
146 | 159 |
147 rvh->GetAudioOutputControllers(base::Bind( | 160 rph->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 |