1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/renderer/media/webrtc_identity_service.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/common/media/webrtc_identity_messages.h" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/renderer/render_thread.h" 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/base/net_errors.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace content { 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochWebRTCIdentityService::RequestInfo::RequestInfo( 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int request_id, 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GURL& origin, 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& identity_name, 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& common_name, 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const SuccessCallback& success_callback, 19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const FailureCallback& failure_callback) 20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : request_id(request_id), 21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch origin(origin), 22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch identity_name(identity_name), 23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch common_name(common_name), 24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch success_callback(success_callback), 25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch failure_callback(failure_callback) {} 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochWebRTCIdentityService::RequestInfo::~RequestInfo() {} 28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochWebRTCIdentityService::WebRTCIdentityService() : next_request_id_(1) { 30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // RenderThread::Get() could be NULL in unit tests. 31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (RenderThread::Get()) 32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RenderThread::Get()->AddObserver(this); 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochWebRTCIdentityService::~WebRTCIdentityService() { 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // RenderThread::Get() could be NULL in unit tests. 37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (RenderThread::Get()) { 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RenderThread::Get()->RemoveObserver(this); 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!pending_requests_.empty()) { 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RenderThread::Get()->Send(new WebRTCIdentityMsg_CancelRequest()); 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 46ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochint WebRTCIdentityService::RequestIdentity( 47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GURL& origin, 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& identity_name, 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& common_name, 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const SuccessCallback& success_callback, 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const FailureCallback& failure_callback) { 52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int request_id = next_request_id_++; 53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch RequestInfo request_info(request_id, 55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch origin, 56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch identity_name, 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch common_name, 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch success_callback, 59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch failure_callback); 60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.push_back(request_info); 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (pending_requests_.size() == 1) 63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SendRequest(request_info); 64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return request_id; 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid WebRTCIdentityService::CancelRequest(int request_id) { 69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::deque<RequestInfo>::iterator it; 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (it = pending_requests_.begin(); it != pending_requests_.end(); ++it) { 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (it->request_id != request_id) 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch continue; 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (it != pending_requests_.begin()) { 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.erase(it); 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else { 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Send(new WebRTCIdentityMsg_CancelRequest()); 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch OnOutstandingRequestReturned(); 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch break; 80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 82ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool WebRTCIdentityService::Send(IPC::Message* message) { 84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Unit tests should override this method to avoid null-ptr-deref. 85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return RenderThread::Get()->Send(message); 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool WebRTCIdentityService::OnControlMessageReceived( 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const IPC::Message& message) { 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool handled = true; 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IPC_BEGIN_MESSAGE_MAP(WebRTCIdentityService, message) 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_IdentityReady, OnIdentityReady) 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IPC_MESSAGE_HANDLER(WebRTCIdentityHostMsg_RequestFailed, OnRequestFailed) 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IPC_MESSAGE_UNHANDLED(handled = false) 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IPC_END_MESSAGE_MAP() 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return handled; 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebRTCIdentityService::OnIdentityReady(int request_id, 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& certificate, 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& private_key) { 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The browser process may have sent the response before it receives the 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // message to cancel the request. So we need to check if the returned response 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // matches the request on the top of the queue. 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pending_requests_.empty() || 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_requests_.front().request_id != request_id) 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.front().success_callback.Run(certificate, private_key); 111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch OnOutstandingRequestReturned(); 112ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WebRTCIdentityService::OnRequestFailed(int request_id, int error) { 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The browser process may have sent the response before it receives the 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // message to cancel the request. So we need to check if the returned response 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // matches the request on the top of the queue. 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pending_requests_.empty() || 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pending_requests_.front().request_id != request_id) 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.front().failure_callback.Run(error); 123ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch OnOutstandingRequestReturned(); 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid WebRTCIdentityService::SendRequest(const RequestInfo& request_info) { 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!Send(new WebRTCIdentityMsg_RequestIdentity(request_info.request_id, 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_info.origin, 129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch request_info.identity_name, 130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch request_info.common_name))) { 131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::MessageLoop::current()->PostTask( 132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch FROM_HERE, 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&WebRTCIdentityService::OnRequestFailed, 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) request_info.request_id, 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch net::ERR_UNEXPECTED)); 137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid WebRTCIdentityService::OnOutstandingRequestReturned() { 141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.pop_front(); 142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!pending_requests_.empty()) 144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SendRequest(pending_requests_.front()); 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace content 148