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 "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" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 : resource_context_(NULL) { | 102 : resource_context_(NULL) { |
103 } | 103 } |
104 | 104 |
105 WebrtcAudioPrivateFunction::~WebrtcAudioPrivateFunction() { | 105 WebrtcAudioPrivateFunction::~WebrtcAudioPrivateFunction() { |
106 } | 106 } |
107 | 107 |
108 void WebrtcAudioPrivateFunction::GetOutputDeviceNames() { | 108 void WebrtcAudioPrivateFunction::GetOutputDeviceNames() { |
109 scoped_refptr<base::SingleThreadTaskRunner> audio_manager_runner = | 109 scoped_refptr<base::SingleThreadTaskRunner> audio_manager_runner = |
110 AudioManager::Get()->GetTaskRunner(); | 110 AudioManager::Get()->GetTaskRunner(); |
111 if (!audio_manager_runner->BelongsToCurrentThread()) { | 111 if (!audio_manager_runner->BelongsToCurrentThread()) { |
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 112 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
113 audio_manager_runner->PostTask( | 113 audio_manager_runner->PostTask( |
114 FROM_HERE, | 114 FROM_HERE, |
115 base::Bind(&WebrtcAudioPrivateFunction::GetOutputDeviceNames, this)); | 115 base::Bind(&WebrtcAudioPrivateFunction::GetOutputDeviceNames, this)); |
116 return; | 116 return; |
117 } | 117 } |
118 | 118 |
119 scoped_ptr<AudioDeviceNames> device_names(new AudioDeviceNames); | 119 scoped_ptr<AudioDeviceNames> device_names(new AudioDeviceNames); |
120 AudioManager::Get()->GetAudioOutputDeviceNames(device_names.get()); | 120 AudioManager::Get()->GetAudioOutputDeviceNames(device_names.get()); |
121 | 121 |
122 BrowserThread::PostTask( | 122 BrowserThread::PostTask( |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 FROM_HERE, | 171 FROM_HERE, |
172 base::Bind(&WebrtcAudioPrivateFunction::OnHMACCalculated, this, hmac)); | 172 base::Bind(&WebrtcAudioPrivateFunction::OnHMACCalculated, this, hmac)); |
173 } | 173 } |
174 | 174 |
175 void WebrtcAudioPrivateFunction::OnHMACCalculated(const std::string& hmac) { | 175 void WebrtcAudioPrivateFunction::OnHMACCalculated(const std::string& hmac) { |
176 NOTREACHED(); | 176 NOTREACHED(); |
177 } | 177 } |
178 | 178 |
179 std::string WebrtcAudioPrivateFunction::CalculateHMACImpl( | 179 std::string WebrtcAudioPrivateFunction::CalculateHMACImpl( |
180 const std::string& raw_id) { | 180 const std::string& raw_id) { |
181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 181 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
182 | 182 |
183 // We don't hash the default device name, and we always return | 183 // We don't hash the default device name, and we always return |
184 // "default" for the default device. There is code in SetActiveSink | 184 // "default" for the default device. There is code in SetActiveSink |
185 // that transforms "default" to the empty string, and code in | 185 // that transforms "default" to the empty string, and code in |
186 // GetActiveSink that ensures we return "default" if we get the | 186 // GetActiveSink that ensures we return "default" if we get the |
187 // empty string as the current device ID. | 187 // empty string as the current device ID. |
188 if (raw_id.empty() || raw_id == media::AudioManagerBase::kDefaultDeviceId) | 188 if (raw_id.empty() || raw_id == media::AudioManagerBase::kDefaultDeviceId) |
189 return media::AudioManagerBase::kDefaultDeviceId; | 189 return media::AudioManagerBase::kDefaultDeviceId; |
190 | 190 |
191 GURL security_origin(source_url().GetOrigin()); | 191 GURL security_origin(source_url().GetOrigin()); |
192 return content::GetHMACForMediaDeviceID( | 192 return content::GetHMACForMediaDeviceID( |
193 resource_context()->GetMediaDeviceIDSalt(), | 193 resource_context()->GetMediaDeviceIDSalt(), |
194 security_origin, | 194 security_origin, |
195 raw_id); | 195 raw_id); |
196 } | 196 } |
197 | 197 |
198 void WebrtcAudioPrivateFunction::InitResourceContext() { | 198 void WebrtcAudioPrivateFunction::InitResourceContext() { |
199 resource_context_ = GetProfile()->GetResourceContext(); | 199 resource_context_ = GetProfile()->GetResourceContext(); |
200 } | 200 } |
201 | 201 |
202 content::ResourceContext* WebrtcAudioPrivateFunction::resource_context() const { | 202 content::ResourceContext* WebrtcAudioPrivateFunction::resource_context() const { |
203 DCHECK(resource_context_); // Did you forget to InitResourceContext()? | 203 DCHECK(resource_context_); // Did you forget to InitResourceContext()? |
204 return resource_context_; | 204 return resource_context_; |
205 } | 205 } |
206 | 206 |
207 bool WebrtcAudioPrivateGetSinksFunction::RunImpl() { | 207 bool WebrtcAudioPrivateGetSinksFunction::RunImpl() { |
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 208 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
209 | 209 |
210 InitResourceContext(); | 210 InitResourceContext(); |
211 GetOutputDeviceNames(); | 211 GetOutputDeviceNames(); |
212 | 212 |
213 return true; | 213 return true; |
214 } | 214 } |
215 | 215 |
216 void WebrtcAudioPrivateGetSinksFunction::OnOutputDeviceNames( | 216 void WebrtcAudioPrivateGetSinksFunction::OnOutputDeviceNames( |
217 scoped_ptr<AudioDeviceNames> raw_ids) { | 217 scoped_ptr<AudioDeviceNames> raw_ids) { |
218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 218 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
219 | 219 |
220 std::vector<linked_ptr<wap::SinkInfo> > results; | 220 std::vector<linked_ptr<wap::SinkInfo> > results; |
221 for (AudioDeviceNames::const_iterator it = raw_ids->begin(); | 221 for (AudioDeviceNames::const_iterator it = raw_ids->begin(); |
222 it != raw_ids->end(); | 222 it != raw_ids->end(); |
223 ++it) { | 223 ++it) { |
224 linked_ptr<wap::SinkInfo> info(new wap::SinkInfo); | 224 linked_ptr<wap::SinkInfo> info(new wap::SinkInfo); |
225 info->sink_id = CalculateHMACImpl(it->unique_id); | 225 info->sink_id = CalculateHMACImpl(it->unique_id); |
226 info->sink_label = it->device_name; | 226 info->sink_label = it->device_name; |
227 // TODO(joi): Add other parameters. | 227 // TODO(joi): Add other parameters. |
228 results.push_back(info); | 228 results.push_back(info); |
(...skipping 13 matching lines...) Expand all Loading... |
242 BrowserThread::UI, | 242 BrowserThread::UI, |
243 FROM_HERE, | 243 FROM_HERE, |
244 base::Bind(&WebrtcAudioPrivateGetSinksFunction::DoneOnUIThread, this)); | 244 base::Bind(&WebrtcAudioPrivateGetSinksFunction::DoneOnUIThread, this)); |
245 } | 245 } |
246 | 246 |
247 void WebrtcAudioPrivateGetSinksFunction::DoneOnUIThread() { | 247 void WebrtcAudioPrivateGetSinksFunction::DoneOnUIThread() { |
248 SendResponse(true); | 248 SendResponse(true); |
249 } | 249 } |
250 | 250 |
251 bool WebrtcAudioPrivateGetActiveSinkFunction::RunImpl() { | 251 bool WebrtcAudioPrivateGetActiveSinkFunction::RunImpl() { |
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 252 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
253 InitResourceContext(); | 253 InitResourceContext(); |
254 | 254 |
255 scoped_ptr<wap::GetActiveSink::Params> params( | 255 scoped_ptr<wap::GetActiveSink::Params> params( |
256 wap::GetActiveSink::Params::Create(*args_)); | 256 wap::GetActiveSink::Params::Create(*args_)); |
257 EXTENSION_FUNCTION_VALIDATE(params.get()); | 257 EXTENSION_FUNCTION_VALIDATE(params.get()); |
258 | 258 |
259 return GetControllerList(params->tab_id); | 259 return GetControllerList(params->tab_id); |
260 } | 260 } |
261 | 261 |
262 void WebrtcAudioPrivateGetActiveSinkFunction::OnControllerList( | 262 void WebrtcAudioPrivateGetActiveSinkFunction::OnControllerList( |
263 const RenderViewHost::AudioOutputControllerList& controllers) { | 263 const RenderViewHost::AudioOutputControllerList& controllers) { |
264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 264 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
265 | 265 |
266 if (controllers.empty()) { | 266 if (controllers.empty()) { |
267 // If there is no current audio stream for the rvh, we return an | 267 // If there is no current audio stream for the rvh, we return an |
268 // empty string as the sink ID. | 268 // empty string as the sink ID. |
269 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: No controllers."; | 269 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: No controllers."; |
270 results_.reset( | 270 results_.reset( |
271 wap::GetActiveSink::Results::Create(std::string()).release()); | 271 wap::GetActiveSink::Results::Create(std::string()).release()); |
272 SendResponse(true); | 272 SendResponse(true); |
273 } else { | 273 } else { |
274 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: " | 274 DVLOG(2) << "chrome.webrtcAudioPrivate.getActiveSink: " |
275 << controllers.size() << " controllers."; | 275 << controllers.size() << " controllers."; |
276 // TODO(joi): Debug-only, DCHECK that all items have the same ID. | 276 // TODO(joi): Debug-only, DCHECK that all items have the same ID. |
277 | 277 |
278 // Send the raw ID through CalculateHMAC, and send the result in | 278 // Send the raw ID through CalculateHMAC, and send the result in |
279 // OnHMACCalculated. | 279 // OnHMACCalculated. |
280 (*controllers.begin())->GetOutputDeviceId( | 280 (*controllers.begin())->GetOutputDeviceId( |
281 base::Bind(&WebrtcAudioPrivateGetActiveSinkFunction::CalculateHMAC, | 281 base::Bind(&WebrtcAudioPrivateGetActiveSinkFunction::CalculateHMAC, |
282 this)); | 282 this)); |
283 } | 283 } |
284 } | 284 } |
285 | 285 |
286 void WebrtcAudioPrivateGetActiveSinkFunction::OnHMACCalculated( | 286 void WebrtcAudioPrivateGetActiveSinkFunction::OnHMACCalculated( |
287 const std::string& hmac_id) { | 287 const std::string& hmac_id) { |
288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 288 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
289 | 289 |
290 std::string result = hmac_id; | 290 std::string result = hmac_id; |
291 if (result.empty()) { | 291 if (result.empty()) { |
292 DVLOG(2) << "Received empty ID, replacing with default ID."; | 292 DVLOG(2) << "Received empty ID, replacing with default ID."; |
293 result = media::AudioManagerBase::kDefaultDeviceId; | 293 result = media::AudioManagerBase::kDefaultDeviceId; |
294 } | 294 } |
295 results_.reset(wap::GetActiveSink::Results::Create(result).release()); | 295 results_.reset(wap::GetActiveSink::Results::Create(result).release()); |
296 SendResponse(true); | 296 SendResponse(true); |
297 } | 297 } |
298 | 298 |
299 WebrtcAudioPrivateSetActiveSinkFunction:: | 299 WebrtcAudioPrivateSetActiveSinkFunction:: |
300 WebrtcAudioPrivateSetActiveSinkFunction() | 300 WebrtcAudioPrivateSetActiveSinkFunction() |
301 : tab_id_(0), | 301 : tab_id_(0), |
302 num_remaining_sink_ids_(0) { | 302 num_remaining_sink_ids_(0) { |
303 } | 303 } |
304 | 304 |
305 WebrtcAudioPrivateSetActiveSinkFunction:: | 305 WebrtcAudioPrivateSetActiveSinkFunction:: |
306 ~WebrtcAudioPrivateSetActiveSinkFunction() { | 306 ~WebrtcAudioPrivateSetActiveSinkFunction() { |
307 } | 307 } |
308 | 308 |
309 bool WebrtcAudioPrivateSetActiveSinkFunction::RunImpl() { | 309 bool WebrtcAudioPrivateSetActiveSinkFunction::RunImpl() { |
310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 310 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
311 scoped_ptr<wap::SetActiveSink::Params> params( | 311 scoped_ptr<wap::SetActiveSink::Params> params( |
312 wap::SetActiveSink::Params::Create(*args_)); | 312 wap::SetActiveSink::Params::Create(*args_)); |
313 EXTENSION_FUNCTION_VALIDATE(params.get()); | 313 EXTENSION_FUNCTION_VALIDATE(params.get()); |
314 | 314 |
315 InitResourceContext(); | 315 InitResourceContext(); |
316 | 316 |
317 tab_id_ = params->tab_id; | 317 tab_id_ = params->tab_id; |
318 sink_id_ = params->sink_id; | 318 sink_id_ = params->sink_id; |
319 | 319 |
320 return GetControllerList(tab_id_); | 320 return GetControllerList(tab_id_); |
321 } | 321 } |
322 | 322 |
323 void WebrtcAudioPrivateSetActiveSinkFunction::OnControllerList( | 323 void WebrtcAudioPrivateSetActiveSinkFunction::OnControllerList( |
324 const RenderViewHost::AudioOutputControllerList& controllers) { | 324 const RenderViewHost::AudioOutputControllerList& controllers) { |
325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 325 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
326 | 326 |
327 controllers_ = controllers; | 327 controllers_ = controllers; |
328 num_remaining_sink_ids_ = controllers_.size(); | 328 num_remaining_sink_ids_ = controllers_.size(); |
329 if (num_remaining_sink_ids_ == 0) { | 329 if (num_remaining_sink_ids_ == 0) { |
330 error_ = extensions::ErrorUtils::FormatErrorMessage( | 330 error_ = extensions::ErrorUtils::FormatErrorMessage( |
331 "No active stream for tab with id: *.", | 331 "No active stream for tab with id: *.", |
332 base::IntToString(tab_id_)); | 332 base::IntToString(tab_id_)); |
333 SendResponse(false); | 333 SendResponse(false); |
334 } else { | 334 } else { |
335 // We need to get the output device names, and calculate the HMAC | 335 // We need to get the output device names, and calculate the HMAC |
336 // for each, to find the raw ID for the ID provided to this API | 336 // for each, to find the raw ID for the ID provided to this API |
337 // function call. | 337 // function call. |
338 GetOutputDeviceNames(); | 338 GetOutputDeviceNames(); |
339 } | 339 } |
340 } | 340 } |
341 | 341 |
342 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceNames( | 342 void WebrtcAudioPrivateSetActiveSinkFunction::OnOutputDeviceNames( |
343 scoped_ptr<AudioDeviceNames> device_names) { | 343 scoped_ptr<AudioDeviceNames> device_names) { |
344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 344 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
345 | 345 |
346 std::string raw_sink_id; | 346 std::string raw_sink_id; |
347 if (sink_id_ == media::AudioManagerBase::kDefaultDeviceId) { | 347 if (sink_id_ == media::AudioManagerBase::kDefaultDeviceId) { |
348 DVLOG(2) << "Received default ID, replacing with empty ID."; | 348 DVLOG(2) << "Received default ID, replacing with empty ID."; |
349 raw_sink_id = ""; | 349 raw_sink_id = ""; |
350 } else { | 350 } else { |
351 for (AudioDeviceNames::const_iterator it = device_names->begin(); | 351 for (AudioDeviceNames::const_iterator it = device_names->begin(); |
352 it != device_names->end(); | 352 it != device_names->end(); |
353 ++it) { | 353 ++it) { |
354 if (sink_id_ == CalculateHMACImpl(it->unique_id)) { | 354 if (sink_id_ == CalculateHMACImpl(it->unique_id)) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 WebrtcAudioPrivateGetAssociatedSinkFunction:: | 386 WebrtcAudioPrivateGetAssociatedSinkFunction:: |
387 WebrtcAudioPrivateGetAssociatedSinkFunction() { | 387 WebrtcAudioPrivateGetAssociatedSinkFunction() { |
388 } | 388 } |
389 | 389 |
390 WebrtcAudioPrivateGetAssociatedSinkFunction:: | 390 WebrtcAudioPrivateGetAssociatedSinkFunction:: |
391 ~WebrtcAudioPrivateGetAssociatedSinkFunction() { | 391 ~WebrtcAudioPrivateGetAssociatedSinkFunction() { |
392 } | 392 } |
393 | 393 |
394 bool WebrtcAudioPrivateGetAssociatedSinkFunction::RunImpl() { | 394 bool WebrtcAudioPrivateGetAssociatedSinkFunction::RunImpl() { |
395 params_ = wap::GetAssociatedSink::Params::Create(*args_); | 395 params_ = wap::GetAssociatedSink::Params::Create(*args_); |
396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 396 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
397 EXTENSION_FUNCTION_VALIDATE(params_.get()); | 397 EXTENSION_FUNCTION_VALIDATE(params_.get()); |
398 | 398 |
399 InitResourceContext(); | 399 InitResourceContext(); |
400 | 400 |
401 AudioManager::Get()->GetTaskRunner()->PostTask( | 401 AudioManager::Get()->GetTaskRunner()->PostTask( |
402 FROM_HERE, | 402 FROM_HERE, |
403 base::Bind(&WebrtcAudioPrivateGetAssociatedSinkFunction:: | 403 base::Bind(&WebrtcAudioPrivateGetAssociatedSinkFunction:: |
404 GetDevicesOnDeviceThread, this)); | 404 GetDevicesOnDeviceThread, this)); |
405 | 405 |
406 return true; | 406 return true; |
407 } | 407 } |
408 | 408 |
409 void WebrtcAudioPrivateGetAssociatedSinkFunction::GetDevicesOnDeviceThread() { | 409 void WebrtcAudioPrivateGetAssociatedSinkFunction::GetDevicesOnDeviceThread() { |
410 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); | 410 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
411 AudioManager::Get()->GetAudioInputDeviceNames(&source_devices_); | 411 AudioManager::Get()->GetAudioInputDeviceNames(&source_devices_); |
412 | 412 |
413 BrowserThread::PostTask( | 413 BrowserThread::PostTask( |
414 BrowserThread::IO, | 414 BrowserThread::IO, |
415 FROM_HERE, | 415 FROM_HERE, |
416 base::Bind(&WebrtcAudioPrivateGetAssociatedSinkFunction:: | 416 base::Bind(&WebrtcAudioPrivateGetAssociatedSinkFunction:: |
417 GetRawSourceIDOnIOThread, | 417 GetRawSourceIDOnIOThread, |
418 this)); | 418 this)); |
419 } | 419 } |
420 | 420 |
421 void | 421 void |
422 WebrtcAudioPrivateGetAssociatedSinkFunction::GetRawSourceIDOnIOThread() { | 422 WebrtcAudioPrivateGetAssociatedSinkFunction::GetRawSourceIDOnIOThread() { |
423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 423 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
424 | 424 |
425 GURL security_origin(params_->security_origin); | 425 GURL security_origin(params_->security_origin); |
426 std::string source_id_in_origin(params_->source_id_in_origin); | 426 std::string source_id_in_origin(params_->source_id_in_origin); |
427 | 427 |
428 // Find the raw source ID for source_id_in_origin. | 428 // Find the raw source ID for source_id_in_origin. |
429 std::string raw_source_id; | 429 std::string raw_source_id; |
430 for (AudioDeviceNames::const_iterator it = source_devices_.begin(); | 430 for (AudioDeviceNames::const_iterator it = source_devices_.begin(); |
431 it != source_devices_.end(); | 431 it != source_devices_.end(); |
432 ++it) { | 432 ++it) { |
433 const std::string& id = it->unique_id; | 433 const std::string& id = it->unique_id; |
(...skipping 27 matching lines...) Expand all Loading... |
461 if (!raw_source_id.empty()) { | 461 if (!raw_source_id.empty()) { |
462 raw_sink_id = | 462 raw_sink_id = |
463 AudioManager::Get()->GetAssociatedOutputDeviceID(raw_source_id); | 463 AudioManager::Get()->GetAssociatedOutputDeviceID(raw_source_id); |
464 } | 464 } |
465 | 465 |
466 CalculateHMAC(raw_sink_id); | 466 CalculateHMAC(raw_sink_id); |
467 } | 467 } |
468 | 468 |
469 void WebrtcAudioPrivateGetAssociatedSinkFunction::OnHMACCalculated( | 469 void WebrtcAudioPrivateGetAssociatedSinkFunction::OnHMACCalculated( |
470 const std::string& associated_sink_id) { | 470 const std::string& associated_sink_id) { |
471 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 471 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
472 | 472 |
473 if (associated_sink_id == media::AudioManagerBase::kDefaultDeviceId) { | 473 if (associated_sink_id == media::AudioManagerBase::kDefaultDeviceId) { |
474 DVLOG(2) << "Got default ID, replacing with empty ID."; | 474 DVLOG(2) << "Got default ID, replacing with empty ID."; |
475 results_.reset(wap::GetAssociatedSink::Results::Create("").release()); | 475 results_.reset(wap::GetAssociatedSink::Results::Create("").release()); |
476 } else { | 476 } else { |
477 results_.reset( | 477 results_.reset( |
478 wap::GetAssociatedSink::Results::Create(associated_sink_id).release()); | 478 wap::GetAssociatedSink::Results::Create(associated_sink_id).release()); |
479 } | 479 } |
480 | 480 |
481 SendResponse(true); | 481 SendResponse(true); |
482 } | 482 } |
483 | 483 |
484 } // namespace extensions | 484 } // namespace extensions |
OLD | NEW |