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

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

Issue 2424163004: Factor out authorization from AudioRendererHost. (Closed)
Patch Set: Dale's comments. 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/media/audio_output_authorization_handler .h"
6
7 #include "base/task_runner_util.h"
8 #include "content/browser/bad_message.h"
9 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/media_device_id.h"
12 #include "media/base/limits.h"
13
14 namespace {
15
16 void MaybeFixAudioParameters(media::AudioParameters* params) {
17 // If the number of output channels is greater than the maximum, use the
18 // maximum allowed value. Hardware channels are ignored upstream, so it is
19 // better to report a valid value if this is the only problem.
20 if (params->channels() > media::limits::kMaxChannels) {
21 DCHECK(params->channel_layout() == media::CHANNEL_LAYOUT_DISCRETE);
22 params->set_channels_for_discrete(media::limits::kMaxChannels);
23 }
24
25 // If hardware parameters are still invalid, use dummy parameters with
26 // fake audio path and let the client handle the error.
27 if (!params->IsValid())
28 *params = media::AudioParameters::UnavailableDeviceParams();
29 }
30
31 media::AudioParameters GetDeviceParametersOnDeviceThread(
32 const std::string& unique_id) {
33 media::AudioManager* audio_manager = media::AudioManager::Get();
34 DCHECK(audio_manager->GetTaskRunner()->BelongsToCurrentThread());
35
36 return media::AudioDeviceDescription::IsDefaultDevice(unique_id)
37 ? audio_manager->GetDefaultOutputStreamParameters()
38 : audio_manager->GetOutputStreamParameters(unique_id);
39 }
40
41 } // namespace
42
43 namespace content {
44
45 AudioOutputAuthorizationHandler::AudioOutputAuthorizationHandler(
46 MediaStreamManager* media_stream_manager,
47 int render_process_id,
48 const std::string& salt)
49 : media_stream_manager_(media_stream_manager),
50 render_process_id_(render_process_id),
51 salt_(salt),
52 weak_factory_(this) {
53 DCHECK(media_stream_manager_);
54 }
55
56 AudioOutputAuthorizationHandler::~AudioOutputAuthorizationHandler() = default;
57
58 void AudioOutputAuthorizationHandler::RequestDeviceAuthorization(
59 int render_frame_id,
60 int session_id,
61 const std::string& device_id,
62 const url::Origin& security_origin,
63 AuthorizationCompletedCallback cb) {
64 DCHECK_CURRENTLY_ON(BrowserThread::IO);
65
66 if (!IsValidDeviceId(device_id)) {
67 bad_message::ReceivedBadMessage(render_process_id_,
68 bad_message::AOAH_NONSENSE_DEVICE_ID);
69 return;
70 }
71
72 // If |session_id| should be used for output device selection and such output
73 // device is found, reuse the input device permissions.
74 if (media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id,
75 device_id)) {
76 const StreamDeviceInfo* info =
77 media_stream_manager_->audio_input_device_manager()
78 ->GetOpenedDeviceInfoById(session_id);
79 if (info) {
80 media::AudioParameters output_params(
81 media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
82 static_cast<media::ChannelLayout>(
83 info->device.matched_output.channel_layout),
84 info->device.matched_output.sample_rate, 16,
85 info->device.matched_output.frames_per_buffer);
86 output_params.set_effects(info->device.matched_output.effects);
87 MaybeFixAudioParameters(&output_params);
88
89 cb.Run(media::OUTPUT_DEVICE_STATUS_OK, std::move(output_params),
o1ka 2016/11/03 10:07:22 remove "move"?
Max Morin 2016/11/10 14:59:52 Done.
90 GetHMACForMediaDeviceID(salt_, security_origin,
91 info->device.matched_output_device_id));
92 return;
93 }
94 }
95
96 CheckOutputDeviceAccess(std::move(cb), render_frame_id, device_id,
97 security_origin);
98 }
99
100 void AudioOutputAuthorizationHandler::CheckOutputDeviceAccess(
101 AuthorizationCompletedCallback cb,
102 int render_frame_id,
103 const std::string& device_id,
104 const url::Origin& security_origin) {
105 DCHECK_CURRENTLY_ON(BrowserThread::IO);
106
107 // Check security origin if nondefault device is requested.
108 // Ignore check for default device, which is always authorized.
109 if (!media::AudioDeviceDescription::IsDefaultDevice(device_id) &&
110 !MediaStreamManager::IsOriginAllowed(render_process_id_,
111 security_origin)) {
112 bad_message::ReceivedBadMessage(render_process_id_,
113 bad_message::AOAH_UNAUTHORIZED_URL);
114 return;
115 }
116
117 if (media::AudioDeviceDescription::IsDefaultDevice(device_id)) {
118 AccessChecked(std::move(cb), device_id, security_origin, true);
119 } else {
120 // Check that MediaStream device permissions have been granted for
121 // nondefault devices.
122 permission_checker_.CheckPermission(
123 MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, render_process_id_, render_frame_id,
124 security_origin,
125 base::Bind(&AudioOutputAuthorizationHandler::AccessChecked,
126 weak_factory_.GetWeakPtr(), std::move(cb), device_id,
127 security_origin));
128 }
129 }
130
131 void AudioOutputAuthorizationHandler::AccessChecked(
132 AuthorizationCompletedCallback cb,
133 const std::string& device_id,
134 const url::Origin& security_origin,
135 bool have_access) {
136 DCHECK_CURRENTLY_ON(BrowserThread::IO);
137
138 if (!have_access) {
139 cb.Run(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED,
140 media::AudioParameters::UnavailableDeviceParams(), std::string());
141 return;
142 }
143
144 // For default device, read output parameters directly. Nondefault devices
145 // require translation first.
146 if (media::AudioDeviceDescription::IsDefaultDevice(device_id)) {
147 base::PostTaskAndReplyWithResult(
148 media::AudioManager::Get()->GetTaskRunner(), FROM_HERE,
149 base::Bind(&GetDeviceParametersOnDeviceThread,
150 media::AudioDeviceDescription::kDefaultDeviceId),
151 base::Bind(&AudioOutputAuthorizationHandler::DeviceParametersReceived,
152 weak_factory_.GetWeakPtr(), std::move(cb), true,
153 media::AudioDeviceDescription::kDefaultDeviceId));
154 } else {
155 MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
156 devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
157 media_stream_manager_->media_devices_manager()->EnumerateDevices(
158 devices_to_enumerate,
159 base::Bind(&AudioOutputAuthorizationHandler::TranslateDeviceID,
160 weak_factory_.GetWeakPtr(), std::move(cb), device_id,
161 security_origin));
162 }
163 }
164
165 void AudioOutputAuthorizationHandler::TranslateDeviceID(
166 AuthorizationCompletedCallback cb,
167 const std::string& device_id,
168 const url::Origin& security_origin,
169 const MediaDeviceEnumeration& enumeration) {
170 DCHECK_CURRENTLY_ON(BrowserThread::IO);
171 DCHECK(!media::AudioDeviceDescription::IsDefaultDevice(device_id));
172 for (const MediaDeviceInfo& device_info :
173 enumeration[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT]) {
174 if (content::DoesMediaDeviceIDMatchHMAC(salt_, security_origin, device_id,
175 device_info.device_id)) {
176 base::PostTaskAndReplyWithResult(
177 media::AudioManager::Get()->GetTaskRunner(), FROM_HERE,
178 base::Bind(&GetDeviceParametersOnDeviceThread, device_info.device_id),
179 base::Bind(&AudioOutputAuthorizationHandler::DeviceParametersReceived,
180 weak_factory_.GetWeakPtr(), std::move(cb), true,
181 device_info.device_id));
o1ka 2016/11/03 10:07:22 +guidou@ - I'm a bit confused: shouldn't we return
Guido Urdaneta 2016/11/03 10:11:52 We should use device_id instead of device_info.dev
Max Morin 2016/11/10 14:59:52 ARH actually needs the translated id. I'll make th
Guido Urdaneta 2016/11/10 15:26:04 Actually you can provide the empty string, as in t
182 return;
183 }
184 }
185 DeviceParametersReceived(std::move(cb), false, std::string(),
186 media::AudioParameters::UnavailableDeviceParams());
187 }
188
189 void AudioOutputAuthorizationHandler::DeviceParametersReceived(
190 AuthorizationCompletedCallback cb,
191 bool device_found,
192 const std::string& unique_id,
o1ka 2016/11/03 10:07:22 we need to name this appropriately (see my comment
Max Morin 2016/11/10 14:59:52 I changed this to translated_device_id.
Guido Urdaneta 2016/11/10 15:26:04 Note that in the original code, |unique_id| was us
193 const media::AudioParameters& output_params) {
194 DCHECK_CURRENTLY_ON(BrowserThread::IO);
195
196 if (!device_found) {
197 cb.Run(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND,
198 media::AudioParameters::UnavailableDeviceParams(), "");
o1ka 2016/11/03 10:07:22 std::string()?
Max Morin 2016/11/10 14:59:52 Done.
199 return;
200 }
201
202 media::AudioParameters output_params_copy(output_params);
203 MaybeFixAudioParameters(&output_params_copy);
204 cb.Run(media::OUTPUT_DEVICE_STATUS_OK, output_params_copy, unique_id);
205 }
206
207 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698