Purge all uses of PassRefPtr in WebCore/Modules
[WebKit-https.git] / Source / WebCore / Modules / mediastream / CaptureDeviceManager.cpp
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "CaptureDeviceManager.h"
28
29 #if ENABLE(MEDIA_STREAM)
30
31 #import "Logging.h"
32 #import "MediaConstraints.h"
33 #import "RealtimeMediaSource.h"
34 #import "RealtimeMediaSourceCenter.h"
35 #import "RealtimeMediaSourceSettings.h"
36 #import "UUID.h"
37 #import <wtf/MainThread.h>
38 #import <wtf/NeverDestroyed.h>
39
40 using namespace WebCore;
41
42 CaptureDeviceManager::~CaptureDeviceManager()
43 {
44 }
45
46 Vector<RefPtr<TrackSourceInfo>> CaptureDeviceManager::getSourcesInfo(const String& requestOrigin)
47 {
48     UNUSED_PARAM(requestOrigin);
49     Vector<RefPtr<TrackSourceInfo>> sourcesInfo;
50     for (auto captureDevice : captureDeviceList()) {
51         if (!captureDevice.m_enabled || captureDevice.m_sourceType == RealtimeMediaSource::None)
52             continue;
53
54         TrackSourceInfo::SourceKind trackSourceType = captureDevice.m_sourceType == RealtimeMediaSource::Video ? TrackSourceInfo::Video : TrackSourceInfo::Audio;
55         sourcesInfo.append(TrackSourceInfo::create(captureDevice.m_persistentDeviceID, captureDevice.m_sourceId, trackSourceType, captureDevice.m_localizedName, captureDevice.m_groupID));
56     }
57     LOG(Media, "CaptureDeviceManager::getSourcesInfo(%p), found %zu active devices", this, sourcesInfo.size());
58     return sourcesInfo;
59 }
60
61 bool CaptureDeviceManager::captureDeviceFromDeviceID(const String& captureDeviceID, CaptureDeviceInfo& foundDevice)
62 {
63     for (auto& device : captureDeviceList()) {
64         if (device.m_persistentDeviceID == captureDeviceID) {
65             foundDevice = device;
66             return true;
67         }
68     }
69
70     return false;
71 }
72
73 bool CaptureDeviceManager::verifyConstraintsForMediaType(RealtimeMediaSource::Type type, MediaConstraints* constraints, const CaptureSessionInfo* session, String& invalidConstraint)
74 {
75     if (!constraints)
76         return true;
77
78     Vector<MediaConstraint> mandatoryConstraints;
79     constraints->getMandatoryConstraints(mandatoryConstraints);
80     for (auto& constraint : mandatoryConstraints) {
81         if (sessionSupportsConstraint(session, type, constraint.m_name, constraint.m_value))
82             continue;
83
84         invalidConstraint = constraint.m_name;
85         return false;
86     }
87
88     return true;
89 }
90
91 Vector<RefPtr<RealtimeMediaSource>> CaptureDeviceManager::bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type type, MediaConstraints& constraints)
92 {
93     Vector<RefPtr<RealtimeMediaSource>> bestSourcesList;
94
95     struct {
96         bool operator()(RefPtr<RealtimeMediaSource> a, RefPtr<RealtimeMediaSource> b)
97         {
98             return a->fitnessScore() < b->fitnessScore();
99         }
100     } sortBasedOnFitnessScore;
101
102     for (auto& captureDevice : captureDeviceList()) {
103         if (!captureDevice.m_enabled || captureDevice.m_sourceId.isEmpty() || captureDevice.m_sourceType == RealtimeMediaSource::None)
104             continue;
105
106         if (RefPtr<RealtimeMediaSource> captureSource = sourceWithUID(captureDevice.m_persistentDeviceID, type, &constraints))
107             bestSourcesList.append(captureSource.leakRef());
108     }
109     std::sort(bestSourcesList.begin(), bestSourcesList.end(), sortBasedOnFitnessScore);
110     return bestSourcesList;
111 }
112
113 RefPtr<RealtimeMediaSource> CaptureDeviceManager::sourceWithUID(const String& deviceUID, RealtimeMediaSource::Type type, MediaConstraints* constraints)
114 {
115     for (auto& captureDevice : captureDeviceList()) {
116         if (captureDevice.m_persistentDeviceID != deviceUID || captureDevice.m_sourceType != type)
117             continue;
118
119         if (!captureDevice.m_enabled || type == RealtimeMediaSource::None || captureDevice.m_sourceId.isEmpty())
120             continue;
121
122         if (RealtimeMediaSource* mediaSource = createMediaSourceForCaptureDeviceWithConstraints(captureDevice, constraints))
123             return mediaSource;
124     }
125     return nullptr;
126 }
127
128 CaptureDeviceInfo* CaptureDeviceManager::bestDeviceForFacingMode(RealtimeMediaSourceSettings::VideoFacingMode facingMode)
129 {
130     if (facingMode == RealtimeMediaSourceSettings::Unknown)
131         return nullptr;
132
133     for (auto& device : captureDeviceList()) {
134         if (device.m_sourceType == RealtimeMediaSource::Video && device.m_position == facingMode)
135             return &device;
136     }
137     return nullptr;
138 }
139
140 static inline RealtimeMediaSourceSettings::VideoFacingMode facingModeFromString(const String& facingModeString)
141 {
142     static NeverDestroyed<AtomicString> userFacingModeString("user", AtomicString::ConstructFromLiteral);
143     static NeverDestroyed<AtomicString> environmentFacingModeString("environment", AtomicString::ConstructFromLiteral);
144     static NeverDestroyed<AtomicString> leftFacingModeString("left", AtomicString::ConstructFromLiteral);
145     static NeverDestroyed<AtomicString> rightFacingModeString("right", AtomicString::ConstructFromLiteral);
146     if (facingModeString == userFacingModeString)
147         return RealtimeMediaSourceSettings::User;
148     if (facingModeString == environmentFacingModeString)
149         return RealtimeMediaSourceSettings::Environment;
150     if (facingModeString == leftFacingModeString)
151         return RealtimeMediaSourceSettings::Left;
152     if (facingModeString == rightFacingModeString)
153         return RealtimeMediaSourceSettings::Right;
154     return RealtimeMediaSourceSettings::Unknown;
155 }
156
157 bool CaptureDeviceManager::sessionSupportsConstraint(const CaptureSessionInfo*, RealtimeMediaSource::Type type, const String& name, const String& value)
158 {
159     const RealtimeMediaSourceSupportedConstraints& supportedConstraints = RealtimeMediaSourceCenter::singleton().supportedConstraints();
160     MediaConstraintType constraint = supportedConstraints.constraintFromName(name);
161     if (!supportedConstraints.supportsConstraint(constraint))
162         return false;
163
164     switch (constraint) {
165     case MediaConstraintType::Width:
166         return type == RealtimeMediaSource::Video;
167
168     case MediaConstraintType::Height:
169         return type == RealtimeMediaSource::Video;
170
171     case MediaConstraintType::FrameRate: {
172         if (type == RealtimeMediaSource::Audio)
173             return false;
174
175         return isSupportedFrameRate(value.toFloat());
176     }
177     case MediaConstraintType::FacingMode: {
178         if (type == RealtimeMediaSource::Audio)
179             return false;
180
181         return bestDeviceForFacingMode(facingModeFromString(value));
182     }
183     default:
184         return false;
185     }
186 }
187
188 bool CaptureDeviceManager::isSupportedFrameRate(float frameRate) const
189 {
190     return 0 < frameRate && frameRate <= 60;
191 }
192
193 #endif // ENABLE(MEDIA_STREAM)