15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Ericsson AB. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3. Neither the name of Ericsson nor the names of its contributors 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * may be used to endorse or promote products derived from this 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * software without specific prior written permission. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/UserMediaRequest.h" 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/Dictionary.h" 377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "bindings/v8/ExceptionState.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/SpaceSplitString.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/mediastream/MediaStreamCenter.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/mediastream/MediaStreamDescriptor.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/MediaConstraintsImpl.h" 4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/MediaStream.h" 4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/mediastream/UserMediaController.h" 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static PassRefPtr<MediaConstraintsImpl> parseOptions(const Dictionary& options, const String& mediaType, ExceptionState& exceptionState) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<MediaConstraintsImpl> constraints; 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Dictionary constraintsDictionary; 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool ok = options.get(mediaType, constraintsDictionary); 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ok && !constraintsDictionary.isUndefinedOrNull()) 5551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) constraints = MediaConstraintsImpl::create(constraintsDictionary, exceptionState); 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool mediaRequested = false; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) options.get(mediaType, mediaRequested); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (mediaRequested) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) constraints = MediaConstraintsImpl::create(); 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return constraints.release(); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 66a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)PassRefPtr<UserMediaRequest> UserMediaRequest::create(ExecutionContext* context, UserMediaController* controller, const Dictionary& options, PassOwnPtr<NavigatorUserMediaSuccessCallback> successCallback, PassOwnPtr<NavigatorUserMediaErrorCallback> errorCallback, ExceptionState& exceptionState) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) RefPtr<MediaConstraintsImpl> audio = parseOptions(options, "audio", exceptionState); 6951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (exceptionState.hadException()) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) RefPtr<MediaConstraintsImpl> video = parseOptions(options, "video", exceptionState); 7351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) if (exceptionState.hadException()) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!audio && !video) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new UserMediaRequest(context, controller, audio.release(), video.release(), successCallback, errorCallback)); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 82a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)UserMediaRequest::UserMediaRequest(ExecutionContext* context, UserMediaController* controller, PassRefPtr<MediaConstraintsImpl> audio, PassRefPtr<MediaConstraintsImpl> video, PassOwnPtr<NavigatorUserMediaSuccessCallback> successCallback, PassOwnPtr<NavigatorUserMediaErrorCallback> errorCallback) 83591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch : ContextLifecycleObserver(context) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_audio(audio) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_video(video) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_controller(controller) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_successCallback(successCallback) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_errorCallback(errorCallback) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)UserMediaRequest::~UserMediaRequest() 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool UserMediaRequest::audio() const 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_audio; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool UserMediaRequest::video() const 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_video; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MediaConstraints* UserMediaRequest::audioConstraints() const 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_audio.get(); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MediaConstraints* UserMediaRequest::videoConstraints() const 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_video.get(); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Document* UserMediaRequest::ownerDocument() 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (ExecutionContext* context = executionContext()) { 119c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) return toDocument(context); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void UserMediaRequest::start() 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_controller) 128591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch m_controller->requestUserMedia(this); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void UserMediaRequest::succeed(PassRefPtr<MediaStreamDescriptor> streamDescriptor) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!executionContext()) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) RefPtr<MediaStream> stream = MediaStream::create(executionContext(), streamDescriptor); 137521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 138521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) MediaStreamTrackVector audioTracks = stream->getAudioTracks(); 139521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) for (MediaStreamTrackVector::iterator iter = audioTracks.begin(); iter != audioTracks.end(); ++iter) { 140521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) (*iter)->component()->source()->setConstraints(m_audio); 141521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 142521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 143521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) MediaStreamTrackVector videoTracks = stream->getVideoTracks(); 144521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) for (MediaStreamTrackVector::iterator iter = videoTracks.begin(); iter != videoTracks.end(); ++iter) { 145521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) (*iter)->component()->source()->setConstraints(m_video); 146521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 147521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_successCallback->handleEvent(stream.get()); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void UserMediaRequest::fail(const String& description) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!executionContext()) 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_errorCallback) { 1571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) RefPtr<NavigatorUserMediaError> error = NavigatorUserMediaError::create(NavigatorUserMediaError::NamePermissionDenied, description, String()); 1585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_errorCallback->handleEvent(error.get()); 1595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 1605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} 1615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 1625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void UserMediaRequest::failConstraint(const String& constraintName, const String& description) 1635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){ 1645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) ASSERT(!constraintName.isEmpty()); 1651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!executionContext()) 1665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return; 1675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 1685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (m_errorCallback) { 1691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) RefPtr<NavigatorUserMediaError> error = NavigatorUserMediaError::create(NavigatorUserMediaError::NameConstraintNotSatisfied, description, constraintName); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_errorCallback->handleEvent(error.get()); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void UserMediaRequest::contextDestroyed() 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<UserMediaRequest> protect(this); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_controller) { 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_controller->cancelUserMediaRequest(this); 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_controller = 0; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 183591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ContextLifecycleObserver::contextDestroyed(); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 187