Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: content/browser/renderer_host/media/audio_renderer_host.cc

Issue 2424163004: Factor out authorization from AudioRendererHost. (Closed)
Patch Set: Don't use separate UI thread for test. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "content/browser/renderer_host/media/audio_renderer_host.h" 5 #include "content/browser/renderer_host/media/audio_renderer_host.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/memory/shared_memory.h" 14 #include "base/memory/shared_memory.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
16 #include "base/process/process.h"
17 #include "content/browser/bad_message.h" 16 #include "content/browser/bad_message.h"
18 #include "content/browser/browser_main_loop.h" 17 #include "content/browser/browser_main_loop.h"
19 #include "content/browser/media/audio_stream_monitor.h" 18 #include "content/browser/media/audio_stream_monitor.h"
20 #include "content/browser/media/capture/audio_mirroring_manager.h" 19 #include "content/browser/media/capture/audio_mirroring_manager.h"
21 #include "content/browser/media/media_devices_permission_checker.h"
22 #include "content/browser/media/media_internals.h" 20 #include "content/browser/media/media_internals.h"
23 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 21 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
24 #include "content/browser/renderer_host/media/audio_sync_reader.h" 22 #include "content/browser/renderer_host/media/audio_sync_reader.h"
25 #include "content/browser/renderer_host/media/media_stream_manager.h" 23 #include "content/browser/renderer_host/media/media_stream_manager.h"
26 #include "content/browser/renderer_host/render_widget_host_impl.h" 24 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
27 #include "content/common/media/audio_messages.h" 25 #include "content/common/media/audio_messages.h"
28 #include "content/public/browser/content_browser_client.h" 26 #include "content/public/browser/content_browser_client.h"
29 #include "content/public/browser/media_device_id.h" 27 #include "content/public/browser/media_device_id.h"
30 #include "content/public/browser/media_observer.h" 28 #include "content/public/browser/media_observer.h"
31 #include "content/public/browser/render_frame_host.h" 29 #include "content/public/browser/render_frame_host.h"
32 #include "content/public/common/content_switches.h"
33 #include "media/audio/audio_device_description.h" 30 #include "media/audio/audio_device_description.h"
34 #include "media/audio/audio_streams_tracker.h" 31 #include "media/audio/audio_streams_tracker.h"
35 #include "media/base/audio_bus.h" 32 #include "media/base/audio_bus.h"
36 #include "media/base/limits.h" 33 #include "media/base/limits.h"
37 34
38 using media::AudioBus; 35 using media::AudioBus;
39 using media::AudioManager; 36 using media::AudioManager;
40 37
41 namespace content { 38 namespace content {
42 39
43 namespace { 40 namespace {
44 41
45 // Tracks the maximum number of simultaneous output streams browser-wide. 42 // Tracks the maximum number of simultaneous output streams browser-wide.
46 // Accessed on IO thread. 43 // Accessed on IO thread.
47 base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker = 44 base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker =
48 LAZY_INSTANCE_INITIALIZER; 45 LAZY_INSTANCE_INITIALIZER;
49 46
50 std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData( 47 std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData(
51 int stream_id, 48 int stream_id,
52 bool authorized, 49 bool authorized,
53 const std::string& device_unique_id) { 50 const std::string& device_unique_id) {
54 return std::make_pair(stream_id, 51 return std::make_pair(stream_id,
55 std::make_pair(authorized, device_unique_id)); 52 std::make_pair(authorized, device_unique_id));
56 } 53 }
57 54
58 bool IsValidDeviceId(const std::string& device_id) {
59 static const std::string::size_type kValidLength = 64;
60
61 if (device_id.empty() ||
62 device_id == media::AudioDeviceDescription::kDefaultDeviceId ||
63 device_id == media::AudioDeviceDescription::kCommunicationsDeviceId) {
64 return true;
65 }
66
67 if (device_id.length() != kValidLength)
68 return false;
69
70 for (const char& c : device_id) {
71 if ((c < 'a' || c > 'f') && (c < '0' || c > '9'))
72 return false;
73 }
74
75 return true;
76 }
77 55
78 void NotifyRenderProcessHostThatAudioStateChanged(int render_process_id) { 56 void NotifyRenderProcessHostThatAudioStateChanged(int render_process_id) {
79 DCHECK_CURRENTLY_ON(BrowserThread::UI); 57 DCHECK_CURRENTLY_ON(BrowserThread::UI);
80 58
81 RenderProcessHost* render_process_host = 59 RenderProcessHost* render_process_host =
82 RenderProcessHost::FromID(render_process_id); 60 RenderProcessHost::FromID(render_process_id);
83 61
84 if (render_process_host) 62 if (render_process_host)
85 render_process_host->AudioStateChanged(); 63 render_process_host->AudioStateChanged();
86 } 64 }
87 65
88 void MaybeFixAudioParameters(media::AudioParameters* params) {
89 // If the number of output channels is greater than the maximum, use the
90 // maximum allowed value. Hardware channels are ignored upstream, so it is
91 // better to report a valid value if this is the only problem.
92 if (params->channels() > media::limits::kMaxChannels)
93 params->set_channels_for_discrete(media::limits::kMaxChannels);
94
95 // If hardware parameters are still invalid, use dummy parameters with
96 // fake audio path and let the client handle the error.
97 if (!params->IsValid())
98 *params = media::AudioParameters::UnavailableDeviceParams();
99 }
100
101 void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time) { 66 void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time) {
102 UMA_HISTOGRAM_CUSTOM_TIMES("Media.Audio.OutputDeviceAuthorizationTime", 67 UMA_HISTOGRAM_CUSTOM_TIMES("Media.Audio.OutputDeviceAuthorizationTime",
103 base::TimeTicks::Now() - auth_start_time, 68 base::TimeTicks::Now() - auth_start_time,
104 base::TimeDelta::FromMilliseconds(1), 69 base::TimeDelta::FromMilliseconds(1),
105 base::TimeDelta::FromMilliseconds(5000), 50); 70 base::TimeDelta::FromMilliseconds(5000), 50);
106 } 71 }
107 72
108 // Check that the routing ID references a valid RenderFrameHost, and run 73 // Check that the routing ID references a valid RenderFrameHost, and run
109 // |callback| on the IO thread with true if the ID is valid. 74 // |callback| on the IO thread with true if the ID is valid.
110 void ValidateRenderFrameId(int render_process_id, 75 void ValidateRenderFrameId(int render_process_id,
111 int render_frame_id, 76 int render_frame_id,
112 const base::Callback<void(bool)>& callback) { 77 const base::Callback<void(bool)>& callback) {
113 DCHECK_CURRENTLY_ON(BrowserThread::UI); 78 DCHECK_CURRENTLY_ON(BrowserThread::UI);
114 const bool frame_exists = 79 const bool frame_exists =
115 !!RenderFrameHost::FromID(render_process_id, render_frame_id); 80 !!RenderFrameHost::FromID(render_process_id, render_frame_id);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 AudioMirroringManager* mirroring_manager, 188 AudioMirroringManager* mirroring_manager,
224 MediaInternals* media_internals, 189 MediaInternals* media_internals,
225 MediaStreamManager* media_stream_manager, 190 MediaStreamManager* media_stream_manager,
226 const std::string& salt) 191 const std::string& salt)
227 : BrowserMessageFilter(AudioMsgStart), 192 : BrowserMessageFilter(AudioMsgStart),
228 render_process_id_(render_process_id), 193 render_process_id_(render_process_id),
229 audio_manager_(audio_manager), 194 audio_manager_(audio_manager),
230 mirroring_manager_(mirroring_manager), 195 mirroring_manager_(mirroring_manager),
231 audio_log_(media_internals->CreateAudioLog( 196 audio_log_(media_internals->CreateAudioLog(
232 media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)), 197 media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)),
233 media_stream_manager_(media_stream_manager),
234 num_playing_streams_(0), 198 num_playing_streams_(0),
235 salt_(salt), 199 salt_(salt),
236 validate_render_frame_id_function_(&ValidateRenderFrameId), 200 validate_render_frame_id_function_(&ValidateRenderFrameId),
237 max_simultaneous_streams_(0) { 201 max_simultaneous_streams_(0),
202 authorization_handler_(media_stream_manager, render_process_id_, salt) {
238 DCHECK(audio_manager_); 203 DCHECK(audio_manager_);
239 DCHECK(media_stream_manager_);
240 } 204 }
241 205
242 AudioRendererHost::~AudioRendererHost() { 206 AudioRendererHost::~AudioRendererHost() {
243 DCHECK_CURRENTLY_ON(BrowserThread::IO); 207 DCHECK_CURRENTLY_ON(BrowserThread::IO);
244 CHECK(audio_entries_.empty()); 208 CHECK(audio_entries_.empty());
245 209
246 // If we had any streams, report UMA stats for the maximum number of 210 // If we had any streams, report UMA stats for the maximum number of
247 // simultaneous streams for this render process and for the whole browser 211 // simultaneous streams for this render process and for the whole browser
248 // process since last reported. 212 // process since last reported.
249 if (max_simultaneous_streams_ > 0) { 213 if (max_simultaneous_streams_ > 0) {
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 } 373 }
410 374
411 void AudioRendererHost::OnRequestDeviceAuthorization( 375 void AudioRendererHost::OnRequestDeviceAuthorization(
412 int stream_id, 376 int stream_id,
413 int render_frame_id, 377 int render_frame_id,
414 int session_id, 378 int session_id,
415 const std::string& device_id, 379 const std::string& device_id,
416 const url::Origin& security_origin) { 380 const url::Origin& security_origin) {
417 DCHECK_CURRENTLY_ON(BrowserThread::IO); 381 DCHECK_CURRENTLY_ON(BrowserThread::IO);
418 const base::TimeTicks auth_start_time = base::TimeTicks::Now(); 382 const base::TimeTicks auth_start_time = base::TimeTicks::Now();
419
420 DVLOG(1) << "AudioRendererHost@" << this << "::OnRequestDeviceAuthorization" 383 DVLOG(1) << "AudioRendererHost@" << this << "::OnRequestDeviceAuthorization"
421 << "(stream_id=" << stream_id 384 << "(stream_id=" << stream_id
422 << ", render_frame_id=" << render_frame_id 385 << ", render_frame_id=" << render_frame_id
423 << ", session_id=" << session_id << ", device_id=" << device_id 386 << ", session_id=" << session_id << ", device_id=" << device_id
424 << ", security_origin=" << security_origin << ")"; 387 << ", security_origin=" << security_origin << ")";
425
426 if (LookupById(stream_id) || IsAuthorizationStarted(stream_id)) 388 if (LookupById(stream_id) || IsAuthorizationStarted(stream_id))
427 return; 389 return;
390 authorizations_.insert(MakeAuthorizationData(stream_id, false, device_id));
391 // Unretained is ok here since |this| owns |authorization_handler_| and
392 // |authorization_handler_| owns the callback.
393 authorization_handler_.RequestDeviceAuthorization(
394 render_frame_id, session_id, device_id, security_origin,
395 base::Bind(&AudioRendererHost::AuthorizationCompleted,
396 base::Unretained(this), stream_id, security_origin,
397 auth_start_time,
398 media::AudioDeviceDescription::UseSessionIdToSelectDevice(
399 session_id, device_id)));
400 }
428 401
429 if (!IsValidDeviceId(device_id)) { 402 void AudioRendererHost::AuthorizationCompleted(
430 UMALogDeviceAuthorizationTime(auth_start_time); 403 int stream_id,
404 url::Origin security_origin,
405 base::TimeTicks auth_start_time,
406 bool should_send_id,
407 media::OutputDeviceStatus status,
408 const media::AudioParameters& params,
409 const std::string& translated_device_id) {
410 DCHECK_CURRENTLY_ON(BrowserThread::IO);
411 auto auth_data = authorizations_.find(stream_id);
412 if (auth_data == authorizations_.end())
413 return; // Stream was closed before finishing authorization
414
415 UMALogDeviceAuthorizationTime(auth_start_time);
416 if (status == media::OUTPUT_DEVICE_STATUS_OK) {
417 auth_data->second.first = true;
418 auth_data->second.second = translated_device_id;
419 if (should_send_id) {
o1ka 2016/11/14 13:24:04 What if we hit audio_output_authorization_handler.
Max Morin 2016/11/16 08:49:49 Fixed. I figured it was always supposed to return
420 std::string hashed_id = MediaStreamManager::GetHMACForMediaDeviceID(
421 salt_, security_origin, translated_device_id);
422 Send(new AudioMsg_NotifyDeviceAuthorized(stream_id, status, params,
423 hashed_id));
424 } else {
425 Send(new AudioMsg_NotifyDeviceAuthorized(stream_id, status, params,
426 std::string()));
427 }
428 } else {
429 authorizations_.erase(auth_data);
431 Send(new AudioMsg_NotifyDeviceAuthorized( 430 Send(new AudioMsg_NotifyDeviceAuthorized(
432 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, 431 stream_id, status, media::AudioParameters::UnavailableDeviceParams(),
433 media::AudioParameters::UnavailableDeviceParams(), std::string())); 432 std::string()));
434 return;
435 } 433 }
436
437 // If |session_id should be used for output device selection and such output
438 // device is found, reuse the input device permissions.
439 if (media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id,
440 device_id)) {
441 const StreamDeviceInfo* info =
442 media_stream_manager_->audio_input_device_manager()
443 ->GetOpenedDeviceInfoById(session_id);
444 if (info) {
445 media::AudioParameters output_params(
446 media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
447 static_cast<media::ChannelLayout>(
448 info->device.matched_output.channel_layout),
449 info->device.matched_output.sample_rate, 16,
450 info->device.matched_output.frames_per_buffer);
451 output_params.set_effects(info->device.matched_output.effects);
452 authorizations_.insert(MakeAuthorizationData(
453 stream_id, true, info->device.matched_output_device_id));
454 MaybeFixAudioParameters(&output_params);
455 UMALogDeviceAuthorizationTime(auth_start_time);
456 // Hash matched device id and pass it to the renderer
457 Send(new AudioMsg_NotifyDeviceAuthorized(
458 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params,
459 GetHMACForMediaDeviceID(salt_, security_origin,
460 info->device.matched_output_device_id)));
461 return;
462 }
463 }
464
465 authorizations_.insert(
466 MakeAuthorizationData(stream_id, false, std::string()));
467 CheckOutputDeviceAccess(render_frame_id, device_id, security_origin,
468 stream_id, auth_start_time);
469 } 434 }
470 435
471 void AudioRendererHost::OnCreateStream(int stream_id, 436 void AudioRendererHost::OnCreateStream(int stream_id,
472 int render_frame_id, 437 int render_frame_id,
473 const media::AudioParameters& params) { 438 const media::AudioParameters& params) {
474 DCHECK_CURRENTLY_ON(BrowserThread::IO); 439 DCHECK_CURRENTLY_ON(BrowserThread::IO);
475 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream" 440 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream"
476 << "(stream_id=" << stream_id << ")"; 441 << "(stream_id=" << stream_id << ")";
477 442
478 // Determine whether to use the device_unique_id from an authorization, or an 443 // Determine whether to use the device_unique_id from an authorization, or an
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 // Inform the RenderProcessHost when there is no more audio playing. 639 // Inform the RenderProcessHost when there is no more audio playing.
675 if (!base::AtomicRefCountDec(&num_playing_streams_)) { 640 if (!base::AtomicRefCountDec(&num_playing_streams_)) {
676 BrowserThread::PostTask( 641 BrowserThread::PostTask(
677 BrowserThread::UI, FROM_HERE, 642 BrowserThread::UI, FROM_HERE,
678 base::Bind(&NotifyRenderProcessHostThatAudioStateChanged, 643 base::Bind(&NotifyRenderProcessHostThatAudioStateChanged,
679 render_process_id_)); 644 render_process_id_));
680 } 645 }
681 } 646 }
682 } 647 }
683 648
649 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
650 DCHECK_CURRENTLY_ON(BrowserThread::IO);
651 return authorizations_.find(stream_id) != authorizations_.end();
652 }
653
684 bool AudioRendererHost::HasActiveAudio() { 654 bool AudioRendererHost::HasActiveAudio() {
685 return !base::AtomicRefCountIsZero(&num_playing_streams_); 655 return !base::AtomicRefCountIsZero(&num_playing_streams_);
686 } 656 }
687 657
688 void AudioRendererHost::CheckOutputDeviceAccess( 658 void AudioRendererHost::OverrideDevicePermissionsForTesting(bool has_access) {
689 int render_frame_id, 659 authorization_handler_.OverridePermissionsForTesting(has_access);
690 const std::string& device_id,
691 const url::Origin& security_origin,
692 int stream_id,
693 base::TimeTicks auth_start_time) {
694 DCHECK_CURRENTLY_ON(BrowserThread::IO);
695
696 // Check security origin if nondefault device is requested.
697 // Ignore check for default device, which is always authorized.
698 if (!media::AudioDeviceDescription::IsDefaultDevice(device_id) &&
699 !MediaStreamManager::IsOriginAllowed(render_process_id_,
700 security_origin)) {
701 content::bad_message::ReceivedBadMessage(this,
702 bad_message::ARH_UNAUTHORIZED_URL);
703 return;
704 }
705
706 if (media::AudioDeviceDescription::IsDefaultDevice(device_id)) {
707 AccessChecked(device_id, security_origin, stream_id, auth_start_time, true);
708 } else {
709 // Check that device permissions have been granted for nondefault devices.
710 MediaDevicesPermissionChecker permission_checker;
711 permission_checker.CheckPermission(
712 MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, render_process_id_, render_frame_id,
713 security_origin,
714 base::Bind(&AudioRendererHost::AccessChecked, this, device_id,
715 security_origin, stream_id, auth_start_time));
716 }
717 } 660 }
718
719 void AudioRendererHost::AccessChecked(
720 const std::string& device_id,
721 const url::Origin& security_origin,
722 int stream_id,
723 base::TimeTicks auth_start_time,
724 bool have_access) {
725 DCHECK_CURRENTLY_ON(BrowserThread::IO);
726
727 const auto& auth_data = authorizations_.find(stream_id);
728 if (auth_data == authorizations_.end()) {
729 // A close request was received while access check was in progress.
730 UMALogDeviceAuthorizationTime(auth_start_time);
731 return;
732 }
733
734 if (!have_access) {
735 authorizations_.erase(auth_data);
736 UMALogDeviceAuthorizationTime(auth_start_time);
737 Send(new AudioMsg_NotifyDeviceAuthorized(
738 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED,
739 media::AudioParameters::UnavailableDeviceParams(), std::string()));
740 return;
741 }
742
743 // For default device, read output parameters directly. Nondefault devices
744 // require translation first.
745 if (media::AudioDeviceDescription::IsDefaultDevice(device_id)) {
746 base::PostTaskAndReplyWithResult(
747 audio_manager_->GetTaskRunner(), FROM_HERE,
748 base::Bind(&AudioRendererHost::GetDeviceParametersOnDeviceThread, this,
749 media::AudioDeviceDescription::kDefaultDeviceId),
750 base::Bind(&AudioRendererHost::DeviceParametersReceived, this,
751 stream_id, auth_start_time, true,
752 media::AudioDeviceDescription::kDefaultDeviceId));
753 } else {
754 MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
755 devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
756 media_stream_manager_->media_devices_manager()->EnumerateDevices(
757 devices_to_enumerate,
758 base::Bind(&AudioRendererHost::TranslateDeviceID, this, device_id,
759 security_origin, stream_id, auth_start_time));
760 }
761 }
762
763 void AudioRendererHost::TranslateDeviceID(
764 const std::string& device_id,
765 const url::Origin& security_origin,
766 int stream_id,
767 base::TimeTicks auth_start_time,
768 const MediaDeviceEnumeration& enumeration) {
769 DCHECK_CURRENTLY_ON(BrowserThread::IO);
770 DCHECK(!media::AudioDeviceDescription::IsDefaultDevice(device_id));
771 for (const MediaDeviceInfo& device_info :
772 enumeration[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT]) {
773 if (content::DoesMediaDeviceIDMatchHMAC(salt_, security_origin, device_id,
774 device_info.device_id)) {
775 base::PostTaskAndReplyWithResult(
776 audio_manager_->GetTaskRunner(), FROM_HERE,
777 base::Bind(&AudioRendererHost::GetDeviceParametersOnDeviceThread,
778 this, device_info.device_id),
779 base::Bind(&AudioRendererHost::DeviceParametersReceived, this,
780 stream_id, auth_start_time, true, device_info.device_id));
781 return;
782 }
783 }
784 DeviceParametersReceived(stream_id, auth_start_time, false, std::string(),
785 media::AudioParameters::UnavailableDeviceParams());
786 }
787
788 media::AudioParameters AudioRendererHost::GetDeviceParametersOnDeviceThread(
789 const std::string& unique_id) {
790 DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
791
792 if (media::AudioDeviceDescription::IsDefaultDevice(unique_id))
793 return audio_manager_->GetDefaultOutputStreamParameters();
794
795 return audio_manager_->GetOutputStreamParameters(unique_id);
796 }
797
798 void AudioRendererHost::DeviceParametersReceived(
799 int stream_id,
800 base::TimeTicks auth_start_time,
801 bool device_found,
802 const std::string& unique_id,
803 const media::AudioParameters& output_params) {
804 DCHECK_CURRENTLY_ON(BrowserThread::IO);
805 const auto& auth_data = authorizations_.find(stream_id);
806
807 // A close request was received while translation was in progress
808 if (auth_data == authorizations_.end()) {
809 UMALogDeviceAuthorizationTime(auth_start_time);
810 return;
811 }
812
813 if (!device_found) {
814 authorizations_.erase(auth_data);
815 UMALogDeviceAuthorizationTime(auth_start_time);
816 Send(new AudioMsg_NotifyDeviceAuthorized(
817 stream_id, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND,
818 media::AudioParameters::UnavailableDeviceParams(),
819 std::string() /* matched_device_id */));
820 return;
821 }
822
823 auth_data->second.first = true;
824 auth_data->second.second = unique_id;
825
826 media::AudioParameters params = std::move(output_params);
827 MaybeFixAudioParameters(&params);
828 UMALogDeviceAuthorizationTime(auth_start_time);
829 Send(new AudioMsg_NotifyDeviceAuthorized(
830 stream_id, media::OUTPUT_DEVICE_STATUS_OK, params,
831 std::string() /* matched_device_id */));
832 }
833
834 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
835 DCHECK_CURRENTLY_ON(BrowserThread::IO);
836 const auto& i = authorizations_.find(stream_id);
837 return i != authorizations_.end();
838 }
839
840 } // namespace content 661 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698