blob: d81320b9e6cf667136a32a6d2e96c30ee01a2657 [file] [log] [blame]
// 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<RequestHandler> {
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>;
~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<base::SingleThreadTaskRunner> signaling_thread_;
scoped_refptr<webrtc::DTLSIdentityRequestObserver> 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<RequestHandler> handler(
new RequestHandler(origin_, observer, identity_name, common_name));
main_thread_->PostTask(FROM_HERE,
base::Bind(&RequestHandler::RequestIdentityOnUIThread, handler));
return true;
}
} // namespace content