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

Side by Side Diff: chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_api.cc

Issue 2784563003: WebRTC Audio private API: removing WebRtcAudioPrivate(Set/Get)ActiveSinkFunction (Closed)
Patch Set: fix for webrtc_audio_private_browsertest Created 3 years, 8 months 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 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"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/task_runner_util.h" 13 #include "base/task_runner_util.h"
14 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" 14 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
15 #include "chrome/browser/extensions/extension_tab_util.h" 15 #include "chrome/browser/extensions/extension_tab_util.h"
16 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
17 #include "content/public/browser/media_device_id.h" 17 #include "content/public/browser/media_device_id.h"
18 #include "content/public/browser/web_contents.h" 18 #include "content/public/browser/web_contents.h"
19 #include "extensions/browser/event_router.h" 19 #include "extensions/browser/event_router.h"
20 #include "extensions/browser/extension_registry.h" 20 #include "extensions/browser/extension_registry.h"
21 #include "extensions/common/error_utils.h" 21 #include "extensions/common/error_utils.h"
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"
25 #include "url/gurl.h" 24 #include "url/gurl.h"
26 #include "url/origin.h" 25 #include "url/origin.h"
27 26
28 namespace extensions { 27 namespace extensions {
29 28
30 using content::BrowserThread; 29 using content::BrowserThread;
31 using content::RenderProcessHost; 30 using content::RenderProcessHost;
32 using media::AudioDeviceDescriptions; 31 using media::AudioDeviceDescriptions;
33 using media::AudioManager; 32 using media::AudioManager;
34 33
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 BrowserThread::IO, FROM_HERE, 129 BrowserThread::IO, FROM_HERE,
131 base::Bind(&WebrtcAudioPrivateFunction::OnOutputDeviceDescriptions, this, 130 base::Bind(&WebrtcAudioPrivateFunction::OnOutputDeviceDescriptions, this,
132 base::Passed(&device_descriptions))); 131 base::Passed(&device_descriptions)));
133 } 132 }
134 133
135 void WebrtcAudioPrivateFunction::OnOutputDeviceDescriptions( 134 void WebrtcAudioPrivateFunction::OnOutputDeviceDescriptions(
136 std::unique_ptr<AudioDeviceDescriptions> device_descriptions) { 135 std::unique_ptr<AudioDeviceDescriptions> device_descriptions) {
137 NOTREACHED(); 136 NOTREACHED();
138 } 137 }
139 138
140 bool WebrtcAudioPrivateFunction::GetControllerList(const RequestInfo& request) {
141 content::RenderProcessHost* rph = nullptr;
142
143 // If |guest_process_id| is defined, directly use this id to find the
144 // corresponding RenderProcessHost.
145 if (request.guest_process_id.get()) {
146 rph = content::RenderProcessHost::FromID(*request.guest_process_id);
147 } else if (request.tab_id.get()) {
148 int tab_id = *request.tab_id;
149 content::WebContents* contents = NULL;
150 if (!ExtensionTabUtil::GetTabById(tab_id, GetProfile(), true, NULL, NULL,
151 &contents, NULL)) {
152 error_ = extensions::ErrorUtils::FormatErrorMessage(
153 extensions::tabs_constants::kTabNotFoundError,
154 base::IntToString(tab_id));
155 return false;
156 }
157 rph = contents->GetRenderProcessHost();
158 } else {
159 return false;
160 }
161
162 if (!rph)
163 return false;
164
165 rph->GetAudioOutputControllers(
166 base::Bind(&WebrtcAudioPrivateFunction::OnControllerList, this));
167 return true;
168 }
169
170 void WebrtcAudioPrivateFunction::OnControllerList(
171 const content::RenderProcessHost::AudioOutputControllerList& list) {
172 NOTREACHED();
173 }
174
175 void WebrtcAudioPrivateFunction::CalculateHMAC(const std::string& raw_id) { 139 void WebrtcAudioPrivateFunction::CalculateHMAC(const std::string& raw_id) {
176 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 140 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
177 BrowserThread::PostTask( 141 BrowserThread::PostTask(
178 BrowserThread::IO, 142 BrowserThread::IO,
179 FROM_HERE, 143 FROM_HERE,
180 base::Bind(&WebrtcAudioPrivateFunction::CalculateHMAC, this, raw_id)); 144 base::Bind(&WebrtcAudioPrivateFunction::CalculateHMAC, this, raw_id));
181 return; 145 return;
182 } 146 }
183 147
184 std::string hmac = CalculateHMACImpl(raw_id); 148 std::string hmac = CalculateHMACImpl(raw_id);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 BrowserThread::PostTask( 216 BrowserThread::PostTask(
253 BrowserThread::UI, 217 BrowserThread::UI,
254 FROM_HERE, 218 FROM_HERE,
255 base::Bind(&WebrtcAudioPrivateGetSinksFunction::DoneOnUIThread, this)); 219 base::Bind(&WebrtcAudioPrivateGetSinksFunction::DoneOnUIThread, this));
256 } 220 }
257 221
258 void WebrtcAudioPrivateGetSinksFunction::DoneOnUIThread() { 222 void WebrtcAudioPrivateGetSinksFunction::DoneOnUIThread() {
259 SendResponse(true); 223 SendResponse(true);
260 } 224 }
261 225
262 bool WebrtcAudioPrivateGetActiveSinkFunction::RunAsync() {
263 DCHECK_CURRENTLY_ON(BrowserThread::UI);
264 InitDeviceIDSalt();
265
266 std::unique_ptr<wap::GetActiveSink::Params> params(
267 wap::GetActiveSink::Params::Create(*args_));
268 EXTENSION_FUNCTION_VALIDATE(params.get());
269
270 return GetControllerList(params->request);
271 }
272
273 void WebrtcAudioPrivateGetActiveSinkFunction::OnControllerList(
274 const RenderProcessHost::AudioOutputControllerList& controllers) {
275 DCHECK_CURRENTLY_ON(BrowserThread::UI);
276
277 if (controllers.empty()) {
278 // If there is no current audio stream for the rvh, we return an
279 // empty string as the sink ID.
280 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: No controllers.";
281 results_.reset(
282 wap::GetActiveSink::Results::Create(std::string()).release());
283 SendResponse(true);
284 } else {
285 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: "
286 << controllers.size() << " controllers.";
287 // TODO(joi): Debug-only, DCHECK that all items have the same ID.
288
289 // Send the raw ID through CalculateHMAC, and send the result in
290 // OnHMACCalculated.
291 (*controllers.begin())->GetOutputDeviceId(
292 base::Bind(&WebrtcAudioPrivateGetActiveSinkFunction::CalculateHMAC,
293 this));
294 }
295 }
296
297 void WebrtcAudioPrivateGetActiveSinkFunction::OnHMACCalculated(
298 const std::string& hmac_id) {
299 DCHECK_CURRENTLY_ON(BrowserThread::UI);
300
301 std::string result = hmac_id;
302 if (result.empty()) {
303 DVLOG(2) << "Received empty ID, replacing with default ID.";
304 result = media::AudioDeviceDescription::kDefaultDeviceId;
305 }
306 results_ = wap::GetActiveSink::Results::Create(result);
307 SendResponse(true);
308 }
309
310 WebrtcAudioPrivateSetActiveSinkFunction::
311 WebrtcAudioPrivateSetActiveSinkFunction()
312 : num_remaining_sink_ids_(0) {
313 }
314
315 WebrtcAudioPrivateSetActiveSinkFunction::
316 ~WebrtcAudioPrivateSetActiveSinkFunction() {
317 }
318
319 bool WebrtcAudioPrivateSetActiveSinkFunction::RunAsync() {
320 DCHECK_CURRENTLY_ON(BrowserThread::UI);
321 std::unique_ptr<wap::SetActiveSink::Params> params(
322 wap::SetActiveSink::Params::Create(*args_));
323 EXTENSION_FUNCTION_VALIDATE(params.get());
324
325 InitDeviceIDSalt();
326
327 if (params->request.guest_process_id.get()) {
328 request_info_.guest_process_id.reset(
329 new int(*params->request.guest_process_id));
330 } else if (params->request.tab_id.get()) {
331 request_info_.tab_id.reset(new int(*params->request.tab_id));
332 } else {
333 return false;
334 }
335
336 sink_id_ = params->sink_id;
337
338 return GetControllerList(request_info_);
339 }
340
341 void WebrtcAudioPrivateSetActiveSinkFunction::OnControllerList(
342 const RenderProcessHost::AudioOutputControllerList& controllers) {
343 DCHECK_CURRENTLY_ON(BrowserThread::UI);
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;
350 } else {
351 requested_process_type = "tabId";
352 requested_process_id = *request_info_.tab_id;
353 }
354
355 controllers_ = controllers;
356 num_remaining_sink_ids_ = controllers_.size();
357 if (num_remaining_sink_ids_ == 0) {
358 error_ = extensions::ErrorUtils::FormatErrorMessage(
359 "No active stream for " + requested_process_type + " *",
360 base::IntToString(requested_process_id));
361 SendResponse(false);
362 } else {
363 // We need to get the output device IDs, and calculate the HMAC
364 // for each, to find the raw ID for the ID provided to this API
365 // function call.
366 GetOutputDeviceDescriptions();
367 }
368 }
369
370 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceDescriptions(
371 std::unique_ptr<AudioDeviceDescriptions> device_descriptions) {
372 DCHECK_CURRENTLY_ON(BrowserThread::IO);
373
374 std::string raw_sink_id;
375 if (sink_id_ == media::AudioDeviceDescription::kDefaultDeviceId) {
376 DVLOG(2) << "Received default ID, replacing with empty ID.";
377 raw_sink_id = "";
378 } else {
379 for (AudioDeviceDescriptions::const_iterator it =
380 device_descriptions->begin();
381 it != device_descriptions->end(); ++it) {
382 if (sink_id_ == CalculateHMACImpl(it->unique_id)) {
383 raw_sink_id = it->unique_id;
384 break;
385 }
386 }
387
388 if (raw_sink_id.empty())
389 DVLOG(2) << "Found no matching raw sink ID for HMAC " << sink_id_;
390 }
391
392 RenderProcessHost::AudioOutputControllerList::const_iterator it =
393 controllers_.begin();
394 for (; it != controllers_.end(); ++it) {
395 (*it)->SwitchOutputDevice(raw_sink_id, base::Bind(
396 &WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone, this));
397 }
398 }
399
400 void WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone() {
401 if (--num_remaining_sink_ids_ == 0) {
402 BrowserThread::PostTask(
403 BrowserThread::UI,
404 FROM_HERE,
405 base::Bind(&WebrtcAudioPrivateSetActiveSinkFunction::DoneOnUIThread,
406 this));
407 }
408 }
409
410 void WebrtcAudioPrivateSetActiveSinkFunction::DoneOnUIThread() {
411 SendResponse(true);
412 }
413
414 WebrtcAudioPrivateGetAssociatedSinkFunction:: 226 WebrtcAudioPrivateGetAssociatedSinkFunction::
415 WebrtcAudioPrivateGetAssociatedSinkFunction() { 227 WebrtcAudioPrivateGetAssociatedSinkFunction() {
416 } 228 }
417 229
418 WebrtcAudioPrivateGetAssociatedSinkFunction:: 230 WebrtcAudioPrivateGetAssociatedSinkFunction::
419 ~WebrtcAudioPrivateGetAssociatedSinkFunction() { 231 ~WebrtcAudioPrivateGetAssociatedSinkFunction() {
420 } 232 }
421 233
422 bool WebrtcAudioPrivateGetAssociatedSinkFunction::RunAsync() { 234 bool WebrtcAudioPrivateGetAssociatedSinkFunction::RunAsync() {
423 params_ = wap::GetAssociatedSink::Params::Create(*args_); 235 params_ = wap::GetAssociatedSink::Params::Create(*args_);
(...skipping 24 matching lines...) Expand all
448 260
449 void 261 void
450 WebrtcAudioPrivateGetAssociatedSinkFunction::GetRawSourceIDOnIOThread() { 262 WebrtcAudioPrivateGetAssociatedSinkFunction::GetRawSourceIDOnIOThread() {
451 DCHECK_CURRENTLY_ON(BrowserThread::IO); 263 DCHECK_CURRENTLY_ON(BrowserThread::IO);
452 264
453 url::Origin security_origin(GURL(params_->security_origin)); 265 url::Origin security_origin(GURL(params_->security_origin));
454 std::string source_id_in_origin(params_->source_id_in_origin); 266 std::string source_id_in_origin(params_->source_id_in_origin);
455 267
456 // Find the raw source ID for source_id_in_origin. 268 // Find the raw source ID for source_id_in_origin.
457 std::string raw_source_id; 269 std::string raw_source_id;
458 for (AudioDeviceDescriptions::const_iterator it = source_devices_.begin(); 270 for (AudioDeviceDescriptions::const_iterator it = source_devices_.begin();
Max Morin 2017/03/31 07:04:20 Could you rewrite this to a "for each" loop, since
o1ka 2017/03/31 09:15:28 All this code will be changed to switch to AudioSy
459 it != source_devices_.end(); ++it) { 271 it != source_devices_.end(); ++it) {
460 const std::string& id = it->unique_id; 272 const std::string& id = it->unique_id;
461 if (content::DoesMediaDeviceIDMatchHMAC(device_id_salt(), security_origin, 273 if (content::DoesMediaDeviceIDMatchHMAC(device_id_salt(), security_origin,
462 source_id_in_origin, id)) { 274 source_id_in_origin, id)) {
463 raw_source_id = id; 275 raw_source_id = id;
464 DVLOG(2) << "Found raw ID " << raw_source_id 276 DVLOG(2) << "Found raw ID " << raw_source_id
465 << " for source ID in origin " << source_id_in_origin; 277 << " for source ID in origin " << source_id_in_origin;
466 break; 278 break;
467 } 279 }
468 } 280 }
(...skipping 29 matching lines...) Expand all
498 DVLOG(2) << "Got default ID, replacing with empty ID."; 310 DVLOG(2) << "Got default ID, replacing with empty ID.";
499 results_ = wap::GetAssociatedSink::Results::Create(""); 311 results_ = wap::GetAssociatedSink::Results::Create("");
500 } else { 312 } else {
501 results_ = wap::GetAssociatedSink::Results::Create(associated_sink_id); 313 results_ = wap::GetAssociatedSink::Results::Create(associated_sink_id);
502 } 314 }
503 315
504 SendResponse(true); 316 SendResponse(true);
505 } 317 }
506 318
507 } // namespace extensions 319 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698