| 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 |