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

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

Issue 880393002: Fix webrtcAudioPrivate API to handle requests from <webview>s. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: for jam's comments Created 5 years, 10 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 "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/task_runner_util.h" 9 #include "base/task_runner_util.h"
10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" 10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
11 #include "chrome/browser/extensions/extension_tab_util.h" 11 #include "chrome/browser/extensions/extension_tab_util.h"
12 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
13 #include "content/public/browser/media_device_id.h" 13 #include "content/public/browser/media_device_id.h"
14 #include "content/public/browser/resource_context.h" 14 #include "content/public/browser/resource_context.h"
15 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "extensions/browser/event_router.h" 16 #include "extensions/browser/event_router.h"
17 #include "extensions/browser/extension_registry.h" 17 #include "extensions/browser/extension_registry.h"
18 #include "extensions/common/error_utils.h" 18 #include "extensions/common/error_utils.h"
19 #include "extensions/common/permissions/permissions_data.h" 19 #include "extensions/common/permissions/permissions_data.h"
20 #include "media/audio/audio_manager_base.h" 20 #include "media/audio/audio_manager_base.h"
21 #include "media/audio/audio_output_controller.h" 21 #include "media/audio/audio_output_controller.h"
22 22
23 namespace extensions { 23 namespace extensions {
24 24
25 using content::BrowserThread; 25 using content::BrowserThread;
26 using content::RenderViewHost; 26 using content::RenderProcessHost;
27 using media::AudioDeviceNames; 27 using media::AudioDeviceNames;
28 using media::AudioManager; 28 using media::AudioManager;
29 29
30 namespace wap = api::webrtc_audio_private; 30 namespace wap = api::webrtc_audio_private;
31 31
32 using api::webrtc_audio_private::RequestInfo;
33
32 static base::LazyInstance< 34 static base::LazyInstance<
33 BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService> > g_factory = 35 BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService> > g_factory =
34 LAZY_INSTANCE_INITIALIZER; 36 LAZY_INSTANCE_INITIALIZER;
35 37
36 WebrtcAudioPrivateEventService::WebrtcAudioPrivateEventService( 38 WebrtcAudioPrivateEventService::WebrtcAudioPrivateEventService(
37 content::BrowserContext* context) 39 content::BrowserContext* context)
38 : browser_context_(context) { 40 : browser_context_(context) {
39 // In unit tests, the SystemMonitor may not be created. 41 // In unit tests, the SystemMonitor may not be created.
40 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); 42 base::SystemMonitor* system_monitor = base::SystemMonitor::Get();
41 if (system_monitor) 43 if (system_monitor)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 base::Bind(&WebrtcAudioPrivateFunction::OnOutputDeviceNames, 125 base::Bind(&WebrtcAudioPrivateFunction::OnOutputDeviceNames,
124 this, 126 this,
125 Passed(&device_names))); 127 Passed(&device_names)));
126 } 128 }
127 129
128 void WebrtcAudioPrivateFunction::OnOutputDeviceNames( 130 void WebrtcAudioPrivateFunction::OnOutputDeviceNames(
129 scoped_ptr<AudioDeviceNames> device_names) { 131 scoped_ptr<AudioDeviceNames> device_names) {
130 NOTREACHED(); 132 NOTREACHED();
131 } 133 }
132 134
133 bool WebrtcAudioPrivateFunction::GetControllerList(int tab_id) { 135 bool WebrtcAudioPrivateFunction::GetControllerList(const RequestInfo& request) {
134 content::WebContents* contents = NULL; 136 content::RenderProcessHost* rhp = NULL;
tommi (sloooow) - chröme 2015/01/30 20:17:39 nit: rph (also, should we use nullptr?)
135 if (!ExtensionTabUtil::GetTabById( 137
136 tab_id, GetProfile(), true, NULL, NULL, &contents, NULL)) { 138 // If |guest_process_id| is defined, directly use this id to find the
137 error_ = extensions::ErrorUtils::FormatErrorMessage( 139 // corresponding RenderProcessHost.
138 extensions::tabs_constants::kTabNotFoundError, 140 if (request.guest_process_id.get()) {
139 base::IntToString(tab_id)); 141 rhp = content::RenderProcessHost::FromID(*request.guest_process_id.get());
142 } else if (request.tab_id.get()) {
143 int tab_id = *request.tab_id.get();
144 content::WebContents* contents = NULL;
145 if (!ExtensionTabUtil::GetTabById(tab_id, GetProfile(), true, NULL, NULL,
146 &contents, NULL)) {
147 error_ = extensions::ErrorUtils::FormatErrorMessage(
148 extensions::tabs_constants::kTabNotFoundError,
149 base::IntToString(tab_id));
150 return false;
151 }
152 rhp = contents->GetRenderProcessHost();
153 } else {
140 return false; 154 return false;
141 } 155 }
142 156
143 RenderViewHost* rvh = contents->GetRenderViewHost(); 157 if (!rhp)
144 if (!rvh)
145 return false; 158 return false;
146 159
147 rvh->GetAudioOutputControllers(base::Bind( 160 rhp->GetAudioOutputControllers(
148 &WebrtcAudioPrivateFunction::OnControllerList, this)); 161 base::Bind(&WebrtcAudioPrivateFunction::OnControllerList, this));
149 return true; 162 return true;
150 } 163 }
151 164
152 void WebrtcAudioPrivateFunction::OnControllerList( 165 void WebrtcAudioPrivateFunction::OnControllerList(
153 const content::RenderViewHost::AudioOutputControllerList& list) { 166 const content::RenderProcessHost::AudioOutputControllerList& list) {
154 NOTREACHED(); 167 NOTREACHED();
155 } 168 }
156 169
157 void WebrtcAudioPrivateFunction::CalculateHMAC(const std::string& raw_id) { 170 void WebrtcAudioPrivateFunction::CalculateHMAC(const std::string& raw_id) {
158 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 171 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
159 BrowserThread::PostTask( 172 BrowserThread::PostTask(
160 BrowserThread::IO, 173 BrowserThread::IO,
161 FROM_HERE, 174 FROM_HERE,
162 base::Bind(&WebrtcAudioPrivateFunction::CalculateHMAC, this, raw_id)); 175 base::Bind(&WebrtcAudioPrivateFunction::CalculateHMAC, this, raw_id));
163 return; 176 return;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 } 260 }
248 261
249 bool WebrtcAudioPrivateGetActiveSinkFunction::RunAsync() { 262 bool WebrtcAudioPrivateGetActiveSinkFunction::RunAsync() {
250 DCHECK_CURRENTLY_ON(BrowserThread::UI); 263 DCHECK_CURRENTLY_ON(BrowserThread::UI);
251 InitResourceContext(); 264 InitResourceContext();
252 265
253 scoped_ptr<wap::GetActiveSink::Params> params( 266 scoped_ptr<wap::GetActiveSink::Params> params(
254 wap::GetActiveSink::Params::Create(*args_)); 267 wap::GetActiveSink::Params::Create(*args_));
255 EXTENSION_FUNCTION_VALIDATE(params.get()); 268 EXTENSION_FUNCTION_VALIDATE(params.get());
256 269
257 return GetControllerList(params->tab_id); 270 return GetControllerList(params->request);
258 } 271 }
259 272
260 void WebrtcAudioPrivateGetActiveSinkFunction::OnControllerList( 273 void WebrtcAudioPrivateGetActiveSinkFunction::OnControllerList(
261 const RenderViewHost::AudioOutputControllerList& controllers) { 274 const RenderProcessHost::AudioOutputControllerList& controllers) {
262 DCHECK_CURRENTLY_ON(BrowserThread::UI); 275 DCHECK_CURRENTLY_ON(BrowserThread::UI);
263 276
264 if (controllers.empty()) { 277 if (controllers.empty()) {
265 // If there is no current audio stream for the rvh, we return an 278 // If there is no current audio stream for the rvh, we return an
266 // empty string as the sink ID. 279 // empty string as the sink ID.
267 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: No controllers."; 280 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: No controllers.";
268 results_.reset( 281 results_.reset(
269 wap::GetActiveSink::Results::Create(std::string()).release()); 282 wap::GetActiveSink::Results::Create(std::string()).release());
270 SendResponse(true); 283 SendResponse(true);
271 } else { 284 } else {
(...skipping 16 matching lines...) Expand all
288 std::string result = hmac_id; 301 std::string result = hmac_id;
289 if (result.empty()) { 302 if (result.empty()) {
290 DVLOG(2) << "Received empty ID, replacing with default ID."; 303 DVLOG(2) << "Received empty ID, replacing with default ID.";
291 result = media::AudioManagerBase::kDefaultDeviceId; 304 result = media::AudioManagerBase::kDefaultDeviceId;
292 } 305 }
293 results_.reset(wap::GetActiveSink::Results::Create(result).release()); 306 results_.reset(wap::GetActiveSink::Results::Create(result).release());
294 SendResponse(true); 307 SendResponse(true);
295 } 308 }
296 309
297 WebrtcAudioPrivateSetActiveSinkFunction:: 310 WebrtcAudioPrivateSetActiveSinkFunction::
298 WebrtcAudioPrivateSetActiveSinkFunction() 311 WebrtcAudioPrivateSetActiveSinkFunction()
299 : tab_id_(0), 312 : num_remaining_sink_ids_(0) {
300 num_remaining_sink_ids_(0) {
301 } 313 }
302 314
303 WebrtcAudioPrivateSetActiveSinkFunction:: 315 WebrtcAudioPrivateSetActiveSinkFunction::
304 ~WebrtcAudioPrivateSetActiveSinkFunction() { 316 ~WebrtcAudioPrivateSetActiveSinkFunction() {
305 } 317 }
306 318
307 bool WebrtcAudioPrivateSetActiveSinkFunction::RunAsync() { 319 bool WebrtcAudioPrivateSetActiveSinkFunction::RunAsync() {
308 DCHECK_CURRENTLY_ON(BrowserThread::UI); 320 DCHECK_CURRENTLY_ON(BrowserThread::UI);
309 scoped_ptr<wap::SetActiveSink::Params> params( 321 scoped_ptr<wap::SetActiveSink::Params> params(
310 wap::SetActiveSink::Params::Create(*args_)); 322 wap::SetActiveSink::Params::Create(*args_));
311 EXTENSION_FUNCTION_VALIDATE(params.get()); 323 EXTENSION_FUNCTION_VALIDATE(params.get());
312 324
313 InitResourceContext(); 325 InitResourceContext();
314 326
315 tab_id_ = params->tab_id; 327 if (params->request.guest_process_id.get()) {
328 request_info_.guest_process_id.reset(
329 new int(*params->request.guest_process_id.get()));
330 } else if (params->request.tab_id.get()) {
331 request_info_.tab_id.reset(new int(*params->request.tab_id.get()));
332 } else {
333 return false;
334 }
335
316 sink_id_ = params->sink_id; 336 sink_id_ = params->sink_id;
317 337
318 return GetControllerList(tab_id_); 338 return GetControllerList(request_info_);
319 } 339 }
320 340
321 void WebrtcAudioPrivateSetActiveSinkFunction::OnControllerList( 341 void WebrtcAudioPrivateSetActiveSinkFunction::OnControllerList(
322 const RenderViewHost::AudioOutputControllerList& controllers) { 342 const RenderProcessHost::AudioOutputControllerList& controllers) {
323 DCHECK_CURRENTLY_ON(BrowserThread::UI); 343 DCHECK_CURRENTLY_ON(BrowserThread::UI);
324 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.get();
350 } else {
351 requested_process_type = "tabId";
352 requested_process_id = *request_info_.tab_id.get();
353 }
354
325 controllers_ = controllers; 355 controllers_ = controllers;
326 num_remaining_sink_ids_ = controllers_.size(); 356 num_remaining_sink_ids_ = controllers_.size();
327 if (num_remaining_sink_ids_ == 0) { 357 if (num_remaining_sink_ids_ == 0) {
328 error_ = extensions::ErrorUtils::FormatErrorMessage( 358 error_ = extensions::ErrorUtils::FormatErrorMessage(
329 "No active stream for tab with id: *.", 359 "No active stream for " + requested_process_type,
330 base::IntToString(tab_id_)); 360 base::IntToString(requested_process_id));
331 SendResponse(false); 361 SendResponse(false);
332 } else { 362 } else {
333 // We need to get the output device names, and calculate the HMAC 363 // We need to get the output device names, and calculate the HMAC
334 // 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
335 // function call. 365 // function call.
336 GetOutputDeviceNames(); 366 GetOutputDeviceNames();
337 } 367 }
338 } 368 }
339 369
340 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceNames( 370 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceNames(
(...skipping 11 matching lines...) Expand all
352 if (sink_id_ == CalculateHMACImpl(it->unique_id)) { 382 if (sink_id_ == CalculateHMACImpl(it->unique_id)) {
353 raw_sink_id = it->unique_id; 383 raw_sink_id = it->unique_id;
354 break; 384 break;
355 } 385 }
356 } 386 }
357 387
358 if (raw_sink_id.empty()) 388 if (raw_sink_id.empty())
359 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_;
360 } 390 }
361 391
362 RenderViewHost::AudioOutputControllerList::const_iterator it = 392 RenderProcessHost::AudioOutputControllerList::const_iterator it =
363 controllers_.begin(); 393 controllers_.begin();
364 for (; it != controllers_.end(); ++it) { 394 for (; it != controllers_.end(); ++it) {
365 (*it)->SwitchOutputDevice(raw_sink_id, base::Bind( 395 (*it)->SwitchOutputDevice(raw_sink_id, base::Bind(
366 &WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone, this)); 396 &WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone, this));
367 } 397 }
368 } 398 }
369 399
370 void WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone() { 400 void WebrtcAudioPrivateSetActiveSinkFunction::SwitchDone() {
371 if (--num_remaining_sink_ids_ == 0) { 401 if (--num_remaining_sink_ids_ == 0) {
372 BrowserThread::PostTask( 402 BrowserThread::PostTask(
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 results_.reset(wap::GetAssociatedSink::Results::Create("").release()); 503 results_.reset(wap::GetAssociatedSink::Results::Create("").release());
474 } else { 504 } else {
475 results_.reset( 505 results_.reset(
476 wap::GetAssociatedSink::Results::Create(associated_sink_id).release()); 506 wap::GetAssociatedSink::Results::Create(associated_sink_id).release());
477 } 507 }
478 508
479 SendResponse(true); 509 SendResponse(true);
480 } 510 }
481 511
482 } // namespace extensions 512 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698