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 <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "extensions/common/permissions/permissions_data.h" | 22 #include "extensions/common/permissions/permissions_data.h" |
23 #include "media/audio/audio_device_description.h" | 23 #include "media/audio/audio_device_description.h" |
24 #include "media/audio/audio_output_controller.h" | 24 #include "media/audio/audio_output_controller.h" |
25 #include "url/gurl.h" | 25 #include "url/gurl.h" |
26 #include "url/origin.h" | 26 #include "url/origin.h" |
27 | 27 |
28 namespace extensions { | 28 namespace extensions { |
29 | 29 |
30 using content::BrowserThread; | 30 using content::BrowserThread; |
31 using content::RenderProcessHost; | 31 using content::RenderProcessHost; |
32 using media::AudioDeviceNames; | 32 using media::AudioDeviceDescriptions; |
33 using media::AudioManager; | 33 using media::AudioManager; |
34 | 34 |
35 namespace wap = api::webrtc_audio_private; | 35 namespace wap = api::webrtc_audio_private; |
36 | 36 |
37 using api::webrtc_audio_private::RequestInfo; | 37 using api::webrtc_audio_private::RequestInfo; |
38 | 38 |
39 static base::LazyInstance< | 39 static base::LazyInstance< |
40 BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService> > g_factory = | 40 BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService> > g_factory = |
41 LAZY_INSTANCE_INITIALIZER; | 41 LAZY_INSTANCE_INITIALIZER; |
42 | 42 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 router->DispatchEventToExtension(extension_id, std::move(event)); | 102 router->DispatchEventToExtension(extension_id, std::move(event)); |
103 } | 103 } |
104 } | 104 } |
105 } | 105 } |
106 | 106 |
107 WebrtcAudioPrivateFunction::WebrtcAudioPrivateFunction() {} | 107 WebrtcAudioPrivateFunction::WebrtcAudioPrivateFunction() {} |
108 | 108 |
109 WebrtcAudioPrivateFunction::~WebrtcAudioPrivateFunction() { | 109 WebrtcAudioPrivateFunction::~WebrtcAudioPrivateFunction() { |
110 } | 110 } |
111 | 111 |
112 void WebrtcAudioPrivateFunction::GetOutputDeviceNames() { | 112 void WebrtcAudioPrivateFunction::GetOutputDeviceDescriptions() { |
113 scoped_refptr<base::SingleThreadTaskRunner> audio_manager_runner = | 113 scoped_refptr<base::SingleThreadTaskRunner> audio_manager_runner = |
114 AudioManager::Get()->GetTaskRunner(); | 114 AudioManager::Get()->GetTaskRunner(); |
115 if (!audio_manager_runner->BelongsToCurrentThread()) { | 115 if (!audio_manager_runner->BelongsToCurrentThread()) { |
116 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 116 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
117 audio_manager_runner->PostTask( | 117 audio_manager_runner->PostTask( |
118 FROM_HERE, | 118 FROM_HERE, |
119 base::Bind(&WebrtcAudioPrivateFunction::GetOutputDeviceNames, this)); | 119 base::Bind(&WebrtcAudioPrivateFunction::GetOutputDeviceDescriptions, |
| 120 this)); |
120 return; | 121 return; |
121 } | 122 } |
122 | 123 |
123 std::unique_ptr<AudioDeviceNames> device_names(new AudioDeviceNames); | 124 std::unique_ptr<AudioDeviceDescriptions> device_descriptions = |
124 AudioManager::Get()->GetAudioOutputDeviceNames(device_names.get()); | 125 base::MakeUnique<AudioDeviceDescriptions>(); |
| 126 AudioManager::Get()->GetAudioOutputDeviceDescriptions( |
| 127 device_descriptions.get()); |
125 | 128 |
126 BrowserThread::PostTask( | 129 BrowserThread::PostTask( |
127 BrowserThread::IO, FROM_HERE, | 130 BrowserThread::IO, FROM_HERE, |
128 base::Bind(&WebrtcAudioPrivateFunction::OnOutputDeviceNames, this, | 131 base::Bind(&WebrtcAudioPrivateFunction::OnOutputDeviceDescriptions, this, |
129 base::Passed(&device_names))); | 132 base::Passed(&device_descriptions))); |
130 } | 133 } |
131 | 134 |
132 void WebrtcAudioPrivateFunction::OnOutputDeviceNames( | 135 void WebrtcAudioPrivateFunction::OnOutputDeviceDescriptions( |
133 std::unique_ptr<AudioDeviceNames> device_names) { | 136 std::unique_ptr<AudioDeviceDescriptions> device_descriptions) { |
134 NOTREACHED(); | 137 NOTREACHED(); |
135 } | 138 } |
136 | 139 |
137 bool WebrtcAudioPrivateFunction::GetControllerList(const RequestInfo& request) { | 140 bool WebrtcAudioPrivateFunction::GetControllerList(const RequestInfo& request) { |
138 content::RenderProcessHost* rph = nullptr; | 141 content::RenderProcessHost* rph = nullptr; |
139 | 142 |
140 // If |guest_process_id| is defined, directly use this id to find the | 143 // If |guest_process_id| is defined, directly use this id to find the |
141 // corresponding RenderProcessHost. | 144 // corresponding RenderProcessHost. |
142 if (request.guest_process_id.get()) { | 145 if (request.guest_process_id.get()) { |
143 rph = content::RenderProcessHost::FromID(*request.guest_process_id); | 146 rph = content::RenderProcessHost::FromID(*request.guest_process_id); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 } | 189 } |
187 | 190 |
188 void WebrtcAudioPrivateFunction::OnHMACCalculated(const std::string& hmac) { | 191 void WebrtcAudioPrivateFunction::OnHMACCalculated(const std::string& hmac) { |
189 NOTREACHED(); | 192 NOTREACHED(); |
190 } | 193 } |
191 | 194 |
192 std::string WebrtcAudioPrivateFunction::CalculateHMACImpl( | 195 std::string WebrtcAudioPrivateFunction::CalculateHMACImpl( |
193 const std::string& raw_id) { | 196 const std::string& raw_id) { |
194 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 197 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
195 | 198 |
196 // We don't hash the default device name, and we always return | 199 // We don't hash the default device description, and we always return |
197 // "default" for the default device. There is code in SetActiveSink | 200 // "default" for the default device. There is code in SetActiveSink |
198 // that transforms "default" to the empty string, and code in | 201 // that transforms "default" to the empty string, and code in |
199 // GetActiveSink that ensures we return "default" if we get the | 202 // GetActiveSink that ensures we return "default" if we get the |
200 // empty string as the current device ID. | 203 // empty string as the current device ID. |
201 if (media::AudioDeviceDescription::IsDefaultDevice(raw_id)) | 204 if (media::AudioDeviceDescription::IsDefaultDevice(raw_id)) |
202 return media::AudioDeviceDescription::kDefaultDeviceId; | 205 return media::AudioDeviceDescription::kDefaultDeviceId; |
203 | 206 |
204 url::Origin security_origin(source_url().GetOrigin()); | 207 url::Origin security_origin(source_url().GetOrigin()); |
205 return content::GetHMACForMediaDeviceID(device_id_salt(), security_origin, | 208 return content::GetHMACForMediaDeviceID(device_id_salt(), security_origin, |
206 raw_id); | 209 raw_id); |
207 } | 210 } |
208 | 211 |
209 void WebrtcAudioPrivateFunction::InitDeviceIDSalt() { | 212 void WebrtcAudioPrivateFunction::InitDeviceIDSalt() { |
210 device_id_salt_ = GetProfile()->GetResourceContext()->GetMediaDeviceIDSalt(); | 213 device_id_salt_ = GetProfile()->GetResourceContext()->GetMediaDeviceIDSalt(); |
211 } | 214 } |
212 | 215 |
213 std::string WebrtcAudioPrivateFunction::device_id_salt() const { | 216 std::string WebrtcAudioPrivateFunction::device_id_salt() const { |
214 return device_id_salt_; | 217 return device_id_salt_; |
215 } | 218 } |
216 | 219 |
217 bool WebrtcAudioPrivateGetSinksFunction::RunAsync() { | 220 bool WebrtcAudioPrivateGetSinksFunction::RunAsync() { |
218 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 221 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
219 | 222 |
220 InitDeviceIDSalt(); | 223 InitDeviceIDSalt(); |
221 GetOutputDeviceNames(); | 224 GetOutputDeviceDescriptions(); |
222 | 225 |
223 return true; | 226 return true; |
224 } | 227 } |
225 | 228 |
226 void WebrtcAudioPrivateGetSinksFunction::OnOutputDeviceNames( | 229 void WebrtcAudioPrivateGetSinksFunction::OnOutputDeviceDescriptions( |
227 std::unique_ptr<AudioDeviceNames> raw_ids) { | 230 std::unique_ptr<AudioDeviceDescriptions> raw_ids) { |
228 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 231 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
229 | 232 |
230 std::vector<wap::SinkInfo> results; | 233 std::vector<wap::SinkInfo> results; |
231 for (const media::AudioDeviceName& name : *raw_ids) { | 234 for (const media::AudioDeviceDescription& description : *raw_ids) { |
232 wap::SinkInfo info; | 235 wap::SinkInfo info; |
233 info.sink_id = CalculateHMACImpl(name.unique_id); | 236 info.sink_id = CalculateHMACImpl(description.unique_id); |
234 info.sink_label = name.device_name; | 237 info.sink_label = description.device_name; |
235 // TODO(joi): Add other parameters. | 238 // TODO(joi): Add other parameters. |
236 results.push_back(std::move(info)); | 239 results.push_back(std::move(info)); |
237 } | 240 } |
238 | 241 |
239 // It's safe to directly set the results here (from a thread other | 242 // It's safe to directly set the results here (from a thread other |
240 // than the UI thread, on which an AsyncExtensionFunction otherwise | 243 // than the UI thread, on which an AsyncExtensionFunction otherwise |
241 // normally runs) because there is one instance of this object per | 244 // normally runs) because there is one instance of this object per |
242 // function call, no actor outside of this object is modifying the | 245 // function call, no actor outside of this object is modifying the |
243 // results_ member, and the different method invocations on this | 246 // results_ member, and the different method invocations on this |
244 // object run strictly in sequence; first RunAsync on the UI thread, | 247 // object run strictly in sequence; first RunAsync on the UI thread, |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 } | 353 } |
351 | 354 |
352 controllers_ = controllers; | 355 controllers_ = controllers; |
353 num_remaining_sink_ids_ = controllers_.size(); | 356 num_remaining_sink_ids_ = controllers_.size(); |
354 if (num_remaining_sink_ids_ == 0) { | 357 if (num_remaining_sink_ids_ == 0) { |
355 error_ = extensions::ErrorUtils::FormatErrorMessage( | 358 error_ = extensions::ErrorUtils::FormatErrorMessage( |
356 "No active stream for " + requested_process_type + " *", | 359 "No active stream for " + requested_process_type + " *", |
357 base::IntToString(requested_process_id)); | 360 base::IntToString(requested_process_id)); |
358 SendResponse(false); | 361 SendResponse(false); |
359 } else { | 362 } else { |
360 // We need to get the output device names, and calculate the HMAC | 363 // We need to get the output device IDs, and calculate the HMAC |
361 // 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 |
362 // function call. | 365 // function call. |
363 GetOutputDeviceNames(); | 366 GetOutputDeviceDescriptions(); |
364 } | 367 } |
365 } | 368 } |
366 | 369 |
367 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceNames( | 370 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceDescriptions( |
368 std::unique_ptr<AudioDeviceNames> device_names) { | 371 std::unique_ptr<AudioDeviceDescriptions> device_descriptions) { |
369 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 372 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
370 | 373 |
371 std::string raw_sink_id; | 374 std::string raw_sink_id; |
372 if (sink_id_ == media::AudioDeviceDescription::kDefaultDeviceId) { | 375 if (sink_id_ == media::AudioDeviceDescription::kDefaultDeviceId) { |
373 DVLOG(2) << "Received default ID, replacing with empty ID."; | 376 DVLOG(2) << "Received default ID, replacing with empty ID."; |
374 raw_sink_id = ""; | 377 raw_sink_id = ""; |
375 } else { | 378 } else { |
376 for (AudioDeviceNames::const_iterator it = device_names->begin(); | 379 for (AudioDeviceDescriptions::const_iterator it = |
377 it != device_names->end(); | 380 device_descriptions->begin(); |
378 ++it) { | 381 it != device_descriptions->end(); ++it) { |
379 if (sink_id_ == CalculateHMACImpl(it->unique_id)) { | 382 if (sink_id_ == CalculateHMACImpl(it->unique_id)) { |
380 raw_sink_id = it->unique_id; | 383 raw_sink_id = it->unique_id; |
381 break; | 384 break; |
382 } | 385 } |
383 } | 386 } |
384 | 387 |
385 if (raw_sink_id.empty()) | 388 if (raw_sink_id.empty()) |
386 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_; |
387 } | 390 } |
388 | 391 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 AudioManager::Get()->GetTaskRunner()->PostTask( | 429 AudioManager::Get()->GetTaskRunner()->PostTask( |
427 FROM_HERE, | 430 FROM_HERE, |
428 base::Bind(&WebrtcAudioPrivateGetAssociatedSinkFunction:: | 431 base::Bind(&WebrtcAudioPrivateGetAssociatedSinkFunction:: |
429 GetDevicesOnDeviceThread, this)); | 432 GetDevicesOnDeviceThread, this)); |
430 | 433 |
431 return true; | 434 return true; |
432 } | 435 } |
433 | 436 |
434 void WebrtcAudioPrivateGetAssociatedSinkFunction::GetDevicesOnDeviceThread() { | 437 void WebrtcAudioPrivateGetAssociatedSinkFunction::GetDevicesOnDeviceThread() { |
435 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); | 438 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
436 AudioManager::Get()->GetAudioInputDeviceNames(&source_devices_); | 439 AudioManager::Get()->GetAudioInputDeviceDescriptions(&source_devices_); |
437 | 440 |
438 BrowserThread::PostTask( | 441 BrowserThread::PostTask( |
439 BrowserThread::IO, | 442 BrowserThread::IO, |
440 FROM_HERE, | 443 FROM_HERE, |
441 base::Bind(&WebrtcAudioPrivateGetAssociatedSinkFunction:: | 444 base::Bind(&WebrtcAudioPrivateGetAssociatedSinkFunction:: |
442 GetRawSourceIDOnIOThread, | 445 GetRawSourceIDOnIOThread, |
443 this)); | 446 this)); |
444 } | 447 } |
445 | 448 |
446 void | 449 void |
447 WebrtcAudioPrivateGetAssociatedSinkFunction::GetRawSourceIDOnIOThread() { | 450 WebrtcAudioPrivateGetAssociatedSinkFunction::GetRawSourceIDOnIOThread() { |
448 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 451 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
449 | 452 |
450 url::Origin security_origin(GURL(params_->security_origin)); | 453 url::Origin security_origin(GURL(params_->security_origin)); |
451 std::string source_id_in_origin(params_->source_id_in_origin); | 454 std::string source_id_in_origin(params_->source_id_in_origin); |
452 | 455 |
453 // Find the raw source ID for source_id_in_origin. | 456 // Find the raw source ID for source_id_in_origin. |
454 std::string raw_source_id; | 457 std::string raw_source_id; |
455 for (AudioDeviceNames::const_iterator it = source_devices_.begin(); | 458 for (AudioDeviceDescriptions::const_iterator it = source_devices_.begin(); |
456 it != source_devices_.end(); | 459 it != source_devices_.end(); ++it) { |
457 ++it) { | |
458 const std::string& id = it->unique_id; | 460 const std::string& id = it->unique_id; |
459 if (content::DoesMediaDeviceIDMatchHMAC(device_id_salt(), security_origin, | 461 if (content::DoesMediaDeviceIDMatchHMAC(device_id_salt(), security_origin, |
460 source_id_in_origin, id)) { | 462 source_id_in_origin, id)) { |
461 raw_source_id = id; | 463 raw_source_id = id; |
462 DVLOG(2) << "Found raw ID " << raw_source_id | 464 DVLOG(2) << "Found raw ID " << raw_source_id |
463 << " for source ID in origin " << source_id_in_origin; | 465 << " for source ID in origin " << source_id_in_origin; |
464 break; | 466 break; |
465 } | 467 } |
466 } | 468 } |
467 | 469 |
(...skipping 28 matching lines...) Expand all Loading... |
496 DVLOG(2) << "Got default ID, replacing with empty ID."; | 498 DVLOG(2) << "Got default ID, replacing with empty ID."; |
497 results_ = wap::GetAssociatedSink::Results::Create(""); | 499 results_ = wap::GetAssociatedSink::Results::Create(""); |
498 } else { | 500 } else { |
499 results_ = wap::GetAssociatedSink::Results::Create(associated_sink_id); | 501 results_ = wap::GetAssociatedSink::Results::Create(associated_sink_id); |
500 } | 502 } |
501 | 503 |
502 SendResponse(true); | 504 SendResponse(true); |
503 } | 505 } |
504 | 506 |
505 } // namespace extensions | 507 } // namespace extensions |
OLD | NEW |