// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/renderer/media/peer_connection_identity_service.h" #include "base/bind.h" #include "base/thread_task_runner_handle.h" #include "content/renderer/media/webrtc_identity_service.h" #include "content/renderer/render_thread_impl.h" namespace content { namespace { // Bridges identity requests between the main render thread and libjingle's // signaling thread. class RequestHandler : public base::RefCountedThreadSafe { public: RequestHandler(const GURL& origin, webrtc::DTLSIdentityRequestObserver* observer, const std::string& identity_name, const std::string& common_name) : signaling_thread_(base::ThreadTaskRunnerHandle::Get()), observer_(observer), origin_(origin), identity_name_(identity_name), common_name_(common_name) {} void RequestIdentityOnUIThread() { int request_id = RenderThreadImpl::current()->get_webrtc_identity_service() ->RequestIdentity(origin_, identity_name_, common_name_, base::Bind(&RequestHandler::OnIdentityReady, this), base::Bind(&RequestHandler::OnRequestFailed, this)); DCHECK_NE(request_id, 0); } private: friend class base::RefCountedThreadSafe; ~RequestHandler() { DCHECK(!observer_.get()); } void OnIdentityReady( const std::string& certificate, const std::string& private_key) { signaling_thread_->PostTask(FROM_HERE, base::Bind(&webrtc::DTLSIdentityRequestObserver::OnSuccess, observer_, certificate, private_key)); signaling_thread_->PostTask(FROM_HERE, base::Bind(&RequestHandler::EnsureReleaseObserverOnSignalingThread, this)); } void OnRequestFailed(int error) { signaling_thread_->PostTask(FROM_HERE, base::Bind(&webrtc::DTLSIdentityRequestObserver::OnFailure, observer_, error)); signaling_thread_->PostTask(FROM_HERE, base::Bind(&RequestHandler::EnsureReleaseObserverOnSignalingThread, this)); } void EnsureReleaseObserverOnSignalingThread() { DCHECK(signaling_thread_->BelongsToCurrentThread()); observer_ = nullptr; } const scoped_refptr signaling_thread_; scoped_refptr observer_; const GURL origin_; const std::string identity_name_; const std::string common_name_; }; } // namespace PeerConnectionIdentityService::PeerConnectionIdentityService(const GURL& origin) : main_thread_(base::ThreadTaskRunnerHandle::Get()), origin_(origin) { signaling_thread_.DetachFromThread(); DCHECK(main_thread_.get()); } PeerConnectionIdentityService::~PeerConnectionIdentityService() { // Typically destructed on libjingle's signaling thread. } bool PeerConnectionIdentityService::RequestIdentity( const std::string& identity_name, const std::string& common_name, webrtc::DTLSIdentityRequestObserver* observer) { DCHECK(signaling_thread_.CalledOnValidThread()); DCHECK(observer); scoped_refptr handler( new RequestHandler(origin_, observer, identity_name, common_name)); main_thread_->PostTask(FROM_HERE, base::Bind(&RequestHandler::RequestIdentityOnUIThread, handler)); return true; } } // namespace content