Changeset 271471 in webkit
- Timestamp:
- Jan 13, 2021, 4:01:37 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 14 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/mediastream/get-user-media-device-id.html (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/platform/mediastream/CaptureDeviceManager.h (modified) (1 diff)
-
Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp (modified) (1 diff)
-
Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h (modified) (1 diff)
-
Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h (modified) (2 diffs)
-
Source/WebCore/platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.h (modified) (2 diffs)
-
Source/WebCore/platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.mm (modified) (3 diffs)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (modified) (2 diffs)
-
Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h (modified) (1 diff)
-
Source/WebKit/UIProcess/UserMediaProcessManager.cpp (modified) (2 diffs)
-
Source/WebKit/UIProcess/UserMediaProcessManager.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r271461 r271471 1 2021-01-13 Jer Noble <jer.noble@apple.com> 2 3 [Cocoa] Support key rotation with HLS-backed encrypted media streams 4 https://bugs.webkit.org/show_bug.cgi?id=220493 5 <rdar://68227709> 6 7 Reviewed by Youenn Fablet. 8 9 Fix a broken layout test; the test enumerates devices, then uses the deviceIds returned to generate 10 constraints for a call to getUserMedia(). However, it assumes all devices will either be of kind 11 'audioinput' or 'videoinput'. If an 'audiooutput' device is returned (as the MockRealtimeMediaSourceCenter 12 does), then the test turns that into a video capture constraint, which fails. 13 14 * fast/mediastream/get-user-media-device-id.html: 15 1 16 2021-01-13 Ryan Haddad <ryanhaddad@apple.com> 2 17 -
trunk/LayoutTests/fast/mediastream/get-user-media-device-id.html
r266166 r271471 26 26 }).then(devices => { 27 27 devices.forEach((device) => { 28 if (device.kind == "audiooutput") 29 return; 28 30 let kind = device.kind == "audioinput" ? "audio" : "video"; 29 31 deviceIds.push({ type: kind, id : device.deviceId}); -
trunk/Source/WebCore/ChangeLog
r271470 r271471 1 2021-01-13 Jer Noble <jer.noble@apple.com> 2 3 [HANG] 496ms to 1360ms in WebCore::AVAudioSessionCaptureDeviceManager::refreshAudioCaptureDevices() 4 https://bugs.webkit.org/show_bug.cgi?id=220471 5 6 Reviewed by Youenn Fablet. 7 8 Refactor RealtimeMediaSourceCenter::getMediaStreamDevices() to take a completion handler, rather than 9 synchronously return a Vector of CaptureDevices. This also requires all CaptureDeviceManager subclasses 10 to support taking a completion handler themselves. By default, all CaptureDeviceManagers will support 11 the CompletionHandler path by just synchronously calling the completion handler with the existing 12 synchronous method. But for AVAudioSessionCaptureDeviceManager, override that default implementation by 13 activating the AVAudioSession on a background thread, and querying that session's inputs on a background 14 thread as well. 15 16 * platform/mediastream/CaptureDeviceManager.h: 17 * platform/mediastream/RealtimeMediaSourceCenter.cpp: 18 (WebCore::RealtimeMediaSourceCenter::getMediaStreamDevices): 19 * platform/mediastream/RealtimeMediaSourceCenter.h: 20 * platform/mediastream/RealtimeMediaSourceFactory.h: 21 (WebCore::AudioCaptureFactory::getSpeakerDevices const): 22 * platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.h: 23 * platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.mm: 24 (WebCore::AVAudioSessionCaptureDeviceManager::audioSessionDeviceWithUID): 25 (WebCore::AVAudioSessionCaptureDeviceManager::scheduleUpdateCaptureDevices): 26 (WebCore::AVAudioSessionCaptureDeviceManager::refreshAudioCaptureDevices): 27 (WebCore::AVAudioSessionCaptureDeviceManager::getCaptureDevices): 28 (WebCore::AVAudioSessionCaptureDeviceManager::activateAudioSession): 29 (WebCore::AVAudioSessionCaptureDeviceManager::retrieveAudioSessionCaptureDevices const): 30 (WebCore::AVAudioSessionCaptureDeviceManager::setAudioCaptureDevices): 31 (WebCore::AVAudioSessionCaptureDeviceManager::audioSessionCaptureDevices): Deleted. 32 1 33 2021-01-13 Jer Noble <jer.noble@apple.com> 2 34 -
trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.h
r249002 r271471 36 36 public: 37 37 virtual const Vector<CaptureDevice>& captureDevices() = 0; 38 virtual void getCaptureDevices(CompletionHandler<void(Vector<CaptureDevice>&&)>&& callback) { callback(copyToVector(captureDevices())); }; 38 39 virtual Optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&) { return WTF::nullopt; } 39 40 -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp
r266166 r271471 113 113 } 114 114 115 Vector<CaptureDevice> RealtimeMediaSourceCenter::getMediaStreamDevices() 116 { 117 Vector<CaptureDevice> result; 118 for (auto& device : audioCaptureFactory().audioCaptureDeviceManager().captureDevices()) { 119 if (device.enabled()) 120 result.append(device); 121 } 122 for (auto& device : audioCaptureFactory().speakerDevices()) { 123 if (device.enabled()) 124 result.append(device); 125 } 126 for (auto& device : videoCaptureFactory().videoCaptureDeviceManager().captureDevices()) { 127 if (device.enabled()) 128 result.append(device); 129 } 130 for (auto& device : displayCaptureFactory().displayCaptureDeviceManager().captureDevices()) { 131 if (device.enabled()) 132 result.append(device); 133 } 134 135 return result; 115 void RealtimeMediaSourceCenter::getMediaStreamDevices(CompletionHandler<void(Vector<CaptureDevice>&&)>&& completion) 116 { 117 class CaptureDeviceAccumulator : public RefCounted<CaptureDeviceAccumulator> { 118 public: 119 static Ref<CaptureDeviceAccumulator> create(CompletionHandler<void(Vector<CaptureDevice>&&)>&& completion) 120 { 121 return adoptRef(*new CaptureDeviceAccumulator(WTFMove(completion))); 122 } 123 124 ~CaptureDeviceAccumulator() 125 { 126 m_completionHandler(WTFMove(m_results)); 127 } 128 129 CompletionHandler<void(Vector<CaptureDevice>&&)> accumulate() 130 { 131 return [this, protectedThis = makeRef(*this)] (Vector<CaptureDevice>&& result) { 132 m_results.appendVector(WTFMove(result)); 133 }; 134 } 135 136 private: 137 explicit CaptureDeviceAccumulator(CompletionHandler<void(Vector<CaptureDevice>&&)>&& completion) 138 : m_completionHandler(WTFMove(completion)) 139 { 140 } 141 142 CompletionHandler<void(Vector<CaptureDevice>&&)> m_completionHandler; 143 Vector<CaptureDevice> m_results; 144 }; 145 146 auto accumulator = CaptureDeviceAccumulator::create([completion = WTFMove(completion)] (auto&& devices) mutable { 147 devices.removeAllMatching([] (auto& captureDevice) { 148 return !captureDevice.enabled(); 149 }); 150 completion(WTFMove(devices)); 151 }); 152 153 audioCaptureFactory().audioCaptureDeviceManager().getCaptureDevices(accumulator->accumulate()); 154 videoCaptureFactory().videoCaptureDeviceManager().getCaptureDevices(accumulator->accumulate()); 155 displayCaptureFactory().displayCaptureDeviceManager().getCaptureDevices(accumulator->accumulate()); 156 audioCaptureFactory().getSpeakerDevices(accumulator->accumulate()); 136 157 } 137 158 -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h
r261373 r271471 67 67 void createMediaStream(Ref<const Logger>&&, NewMediaStreamHandler&&, String&&, CaptureDevice&& audioDevice, CaptureDevice&& videoDevice, const MediaStreamRequest&); 68 68 69 WEBCORE_EXPORT Vector<CaptureDevice> getMediaStreamDevices();69 WEBCORE_EXPORT void getMediaStreamDevices(CompletionHandler<void(Vector<CaptureDevice>&&)>&&); 70 70 71 71 const RealtimeMediaSourceSupportedConstraints& supportedConstraints() { return m_supportedConstraints; } -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceFactory.h
r271049 r271471 28 28 #if ENABLE(MEDIA_STREAM) 29 29 30 #include <wtf/CompletionHandler.h> 30 31 #include <wtf/WeakPtr.h> 31 32 #include <wtf/text/WTFString.h> … … 63 64 virtual CaptureDeviceManager& audioCaptureDeviceManager() = 0; 64 65 virtual const Vector<CaptureDevice>& speakerDevices() const = 0; 66 virtual void getSpeakerDevices(CompletionHandler<void(Vector<CaptureDevice>&&)>&& completion) const { completion(copyToVector(speakerDevices())); } 65 67 66 68 class ExtensiveObserver : public CanMakeWeakPtr<ExtensiveObserver> { }; -
trunk/Source/WebCore/platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.h
r271049 r271471 49 49 50 50 const Vector<CaptureDevice>& captureDevices() final; 51 void getCaptureDevices(CompletionHandler<void(Vector<CaptureDevice>&&)>&&) final; 51 52 const Vector<CaptureDevice>& speakerDevices() const { return m_speakerDevices; } 52 53 Optional<CaptureDevice> captureDeviceWithPersistentID(CaptureDevice::DeviceType, const String&); … … 64 65 65 66 void createAudioSession(); 67 void activateAudioSession(); 66 68 void refreshAudioCaptureDevices(); 67 Vector<AVAudioSessionCaptureDevice>& audioSessionCaptureDevices(); 69 Vector<AVAudioSessionCaptureDevice> retrieveAudioSessionCaptureDevices() const; 70 void setAudioCaptureDevices(Vector<AVAudioSessionCaptureDevice>&&); 68 71 69 72 enum class AudioSessionState { NotNeeded, Inactive, Active }; -
trunk/Source/WebCore/platform/mediastream/ios/AVAudioSessionCaptureDeviceManager.mm
r271049 r271471 137 137 } 138 138 139 Vector<AVAudioSessionCaptureDevice>& AVAudioSessionCaptureDeviceManager::audioSessionCaptureDevices()139 Optional<AVAudioSessionCaptureDevice> AVAudioSessionCaptureDeviceManager::audioSessionDeviceWithUID(const String& deviceID) 140 140 { 141 141 if (!m_audioSessionCaptureDevices) 142 142 refreshAudioCaptureDevices(); 143 return m_audioSessionCaptureDevices.value(); 144 } 145 146 Optional<AVAudioSessionCaptureDevice> AVAudioSessionCaptureDeviceManager::audioSessionDeviceWithUID(const String& deviceID) 147 { 148 for (auto& device : audioSessionCaptureDevices()) { 143 144 for (auto& device : *m_audioSessionCaptureDevices) { 149 145 if (device.persistentId() == deviceID) 150 146 return device; … … 155 151 void AVAudioSessionCaptureDeviceManager::scheduleUpdateCaptureDevices() 156 152 { 157 if (m_updateDeviceStateQueue.hasPendingTasks()) 158 return; 159 160 m_updateDeviceStateQueue.enqueueTask([this] { 161 refreshAudioCaptureDevices(); 162 }); 153 getCaptureDevices([] (auto) { }); 163 154 } 164 155 165 156 void AVAudioSessionCaptureDeviceManager::refreshAudioCaptureDevices() 166 157 { 167 {168 // Make sure we have created the audio session.169 auto locker = holdLock(m_lock);170 }171 bool firstTime = !m_devices;172 158 if (m_audioSessionState == AudioSessionState::Inactive) { 173 159 m_audioSessionState = AudioSessionState::Active; 174 160 175 if (!m_listener) 176 m_listener = adoptNS([[WebAVAudioSessionAvailableInputsListener alloc] initWithCallback:this audioSession:m_audioSession.get()]); 177 178 NSError *error = nil; 179 [m_audioSession setActive:YES withOptions:0 error:&error]; 180 if (error) 181 RELEASE_LOG_ERROR(WebRTC, "Failed to activate audio session with error: %@.", error.localizedDescription); 161 dispatch_sync(m_dispatchQueue, makeBlockPtr([this] { 162 activateAudioSession(); 163 }).get()); 182 164 } 183 165 184 166 Vector<AVAudioSessionCaptureDevice> newAudioDevices; 185 Vector<CaptureDevice> newDevices; 167 dispatch_sync(m_dispatchQueue, makeBlockPtr([&] { 168 newAudioDevices = retrieveAudioSessionCaptureDevices(); 169 }).get()); 170 setAudioCaptureDevices(WTFMove(newAudioDevices)); 171 } 172 173 void AVAudioSessionCaptureDeviceManager::getCaptureDevices(CompletionHandler<void(Vector<CaptureDevice>&&)>&& completion) 174 { 175 if (m_audioSessionState == AudioSessionState::Inactive) { 176 m_audioSessionState = AudioSessionState::Active; 177 178 dispatch_async(m_dispatchQueue, makeBlockPtr([this] { 179 activateAudioSession(); 180 }).get()); 181 } 182 183 dispatch_async(m_dispatchQueue, makeBlockPtr([this, completion = WTFMove(completion)] () mutable { 184 auto newAudioDevices = retrieveAudioSessionCaptureDevices(); 185 callOnWebThreadOrDispatchAsyncOnMainThread(makeBlockPtr([this, completion = WTFMove(completion), newAudioDevices = WTFMove(newAudioDevices)] () mutable { 186 setAudioCaptureDevices(WTFMove(newAudioDevices)); 187 completion(copyToVector(*m_devices)); 188 }).get()); 189 }).get()); 190 } 191 192 void AVAudioSessionCaptureDeviceManager::activateAudioSession() 193 { 194 if (!m_listener) 195 m_listener = adoptNS([[WebAVAudioSessionAvailableInputsListener alloc] initWithCallback:this audioSession:m_audioSession.get()]); 196 197 NSError *error = nil; 198 [m_audioSession setActive:YES withOptions:0 error:&error]; 199 if (error) 200 RELEASE_LOG_ERROR(WebRTC, "Failed to activate audio session with error: %@.", error.localizedDescription); 201 } 202 203 Vector<AVAudioSessionCaptureDevice> AVAudioSessionCaptureDeviceManager::retrieveAudioSessionCaptureDevices() const 204 { 205 Vector<AVAudioSessionCaptureDevice> newAudioDevices; 186 206 auto *defaultInput = [m_audioSession currentRoute].inputs.firstObject; 187 for (AVAudioSessionPortDescription *portDescription in [m_audioSession availableInputs]) { 188 auto audioDevice = AVAudioSessionCaptureDevice::create(portDescription, defaultInput); 189 newDevices.append(audioDevice); 190 newAudioDevices.append(WTFMove(audioDevice)); 191 } 192 207 newAudioDevices.reserveInitialCapacity([m_audioSession availableInputs].count); 208 209 for (AVAudioSessionPortDescription *portDescription in [m_audioSession availableInputs]) 210 newAudioDevices.uncheckedAppend(AVAudioSessionCaptureDevice::create(portDescription, defaultInput)); 211 212 return newAudioDevices; 213 } 214 215 void AVAudioSessionCaptureDeviceManager::setAudioCaptureDevices(Vector<AVAudioSessionCaptureDevice>&& newAudioDevices) 216 { 217 bool firstTime = !m_devices; 193 218 bool haveDeviceChanges = !m_devices || newAudioDevices.size() != m_devices->size(); 194 219 if (!haveDeviceChanges) { … … 204 229 return; 205 230 231 auto newDevices = copyToVectorOf<CaptureDevice>(newAudioDevices); 206 232 m_audioSessionCaptureDevices = WTFMove(newAudioDevices); 207 233 std::sort(newDevices.begin(), newDevices.end(), [] (auto& first, auto& second) -> bool { -
trunk/Source/WebKit/ChangeLog
r271469 r271471 1 2021-01-13 Jer Noble <jer.noble@apple.com> 2 3 [HANG] 496ms to 1360ms in WebCore::AVAudioSessionCaptureDeviceManager::refreshAudioCaptureDevices() 4 https://bugs.webkit.org/show_bug.cgi?id=220471 5 6 Reviewed by Youenn Fablet. 7 8 Use the completion-handler version of RealtimeMediaSourceCenter::getMediaStreamDevices(). 9 10 * UIProcess/UserMediaPermissionRequestManagerProxy.cpp: 11 (WebKit::UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList): 12 (WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame): 13 * UIProcess/UserMediaPermissionRequestManagerProxy.h: 14 * UIProcess/UserMediaProcessManager.cpp: 15 (WebKit::UserMediaProcessManager::updateCaptureDevices): 16 (WebKit::UserMediaProcessManager::beginMonitoringCaptureDevices): 17 * UIProcess/UserMediaProcessManager.h: 18 1 19 2021-01-13 Per Arne Vollan <pvollan@apple.com> 2 20 -
trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
r271396 r271471 660 660 } 661 661 662 Vector<CaptureDevice> UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList(bool revealIdsAndLabels) 663 { 664 static const int defaultMaximumCameraCount = 1; 665 static const int defaultMaximumMicrophoneCount = 1; 666 667 auto devices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices(); 668 int cameraCount = 0; 669 int microphoneCount = 0; 670 671 Vector<CaptureDevice> filteredDevices; 672 for (const auto& device : devices) { 673 if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone && device.type() != WebCore::CaptureDevice::DeviceType::Speaker)) 674 continue; 675 676 if (!revealIdsAndLabels) { 677 if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount) 662 void UserMediaPermissionRequestManagerProxy::computeFilteredDeviceList(bool revealIdsAndLabels, CompletionHandler<void(Vector<CaptureDevice>&&)>&& completion) 663 { 664 static const unsigned defaultMaximumCameraCount = 1; 665 static const unsigned defaultMaximumMicrophoneCount = 1; 666 667 RealtimeMediaSourceCenter::singleton().getMediaStreamDevices([this, weakThis = makeWeakPtr(this), revealIdsAndLabels, completion = WTFMove(completion)] (auto&& devices) mutable { 668 unsigned cameraCount = 0; 669 unsigned microphoneCount = 0; 670 671 Vector<CaptureDevice> filteredDevices; 672 for (const auto& device : devices) { 673 if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone && device.type() != WebCore::CaptureDevice::DeviceType::Speaker)) 678 674 continue; 679 if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount) 680 continue; 681 if (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone) 682 continue; 683 } else { 684 // We only expose speakers tied to a microphone for the moment. 685 if (device.type() == WebCore::CaptureDevice::DeviceType::Speaker && !haveMicrophoneDevice(devices, device.groupId())) 686 continue; 675 676 if (!revealIdsAndLabels) { 677 if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount) 678 continue; 679 if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount) 680 continue; 681 if (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone) 682 continue; 683 } else { 684 // We only expose speakers tied to a microphone for the moment. 685 if (device.type() == WebCore::CaptureDevice::DeviceType::Speaker && !haveMicrophoneDevice(devices, device.groupId())) 686 continue; 687 } 688 689 filteredDevices.append(revealIdsAndLabels ? device : CaptureDevice({ }, device.type(), { }, { })); 687 690 } 688 691 689 filteredDevices.append(revealIdsAndLabels ? device : CaptureDevice({ }, device.type(), { }, { })); 690 } 691 692 m_hasFilteredDeviceList = !revealIdsAndLabels; 693 694 ALWAYS_LOG(LOGIDENTIFIER, filteredDevices.size(), " devices revealed"); 695 return filteredDevices; 692 if (weakThis) 693 m_hasFilteredDeviceList = !revealIdsAndLabels; 694 695 ALWAYS_LOG(LOGIDENTIFIER, filteredDevices.size(), " devices revealed"); 696 completion(WTFMove(filteredDevices)); 697 }); 696 698 } 697 699 #endif … … 745 747 746 748 callCompletionHandler.release(); 747 completionHandler(computeFilteredDeviceList(revealIdsAndLabels), deviceIDHashSalt); 749 computeFilteredDeviceList(revealIdsAndLabels, [completionHandler = WTFMove(completionHandler), deviceIDHashSalt = WTFMove(deviceIDHashSalt)] (auto&& devices) mutable { 750 completionHandler(devices, deviceIDHashSalt); 751 }); 748 752 }); 749 753 }; -
trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h
r271396 r271471 121 121 bool wasGrantedVideoOrAudioAccess(WebCore::FrameIdentifier, const WebCore::SecurityOrigin& userMediaDocumentOrigin, const WebCore::SecurityOrigin& topLevelDocumentOrigin); 122 122 123 Vector<WebCore::CaptureDevice> computeFilteredDeviceList(bool revealIdsAndLabels);123 void computeFilteredDeviceList(bool revealIdsAndLabels, CompletionHandler<void(Vector<WebCore::CaptureDevice>&&)>&&); 124 124 125 125 void processUserMediaPermissionRequest(); -
trunk/Source/WebKit/UIProcess/UserMediaProcessManager.cpp
r271154 r271471 218 218 } 219 219 220 void UserMediaProcessManager::updateCaptureDevices(ShouldNotify shouldNotify) 221 { 222 WebCore::RealtimeMediaSourceCenter::singleton().getMediaStreamDevices([this, shouldNotify] (auto&& newDevices) mutable { 223 auto oldDevices = WTFMove(m_captureDevices); 224 m_captureDevices = WTFMove(newDevices); 225 226 if (shouldNotify == ShouldNotify::No) 227 return; 228 229 if (m_captureDevices.size() == oldDevices.size()) { 230 bool haveChanges = false; 231 for (auto &newDevice : m_captureDevices) { 232 if (newDevice.type() != WebCore::CaptureDevice::DeviceType::Camera && newDevice.type() != WebCore::CaptureDevice::DeviceType::Microphone) 233 continue; 234 235 auto index = oldDevices.findMatching([&newDevice] (auto& oldDevice) { 236 return newDevice.persistentId() == oldDevice.persistentId() && newDevice.enabled() != oldDevice.enabled(); 237 }); 238 239 if (index == notFound) { 240 haveChanges = true; 241 break; 242 } 243 } 244 245 if (!haveChanges) 246 return; 247 } 248 249 // When a device with camera and microphone is attached or detached, the CaptureDevice notification for 250 // the different devices won't arrive at the same time so delay a bit so we can coalesce the callbacks. 251 if (!m_debounceTimer.isActive()) 252 m_debounceTimer.startOneShot(deviceChangeDebounceTimerInterval); 253 }); 254 } 255 220 256 void UserMediaProcessManager::beginMonitoringCaptureDevices() 221 257 { … … 223 259 224 260 std::call_once(onceFlag, [this] { 225 m_captureDevices = WebCore::RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();261 updateCaptureDevices(ShouldNotify::No); 226 262 227 263 WebCore::RealtimeMediaSourceCenter::singleton().setDevicesChangedObserver([this]() { 228 auto oldDevices = WTFMove(m_captureDevices); 229 m_captureDevices = WebCore::RealtimeMediaSourceCenter::singleton().getMediaStreamDevices(); 230 231 if (m_captureDevices.size() == oldDevices.size()) { 232 bool haveChanges = false; 233 for (auto &newDevice : m_captureDevices) { 234 if (newDevice.type() != WebCore::CaptureDevice::DeviceType::Camera && newDevice.type() != WebCore::CaptureDevice::DeviceType::Microphone) 235 continue; 236 237 auto index = oldDevices.findMatching([&newDevice] (auto& oldDevice) { 238 return newDevice.persistentId() == oldDevice.persistentId() && newDevice.enabled() != oldDevice.enabled(); 239 }); 240 241 if (index == notFound) { 242 haveChanges = true; 243 break; 244 } 245 } 246 247 if (!haveChanges) 248 return; 249 } 250 251 // When a device with camera and microphone is attached or detached, the CaptureDevice notification for 252 // the different devices won't arrive at the same time so delay a bit so we can coalesce the callbacks. 253 if (!m_debounceTimer.isActive()) 254 m_debounceTimer.startOneShot(deviceChangeDebounceTimerInterval); 264 updateCaptureDevices(ShouldNotify::Yes); 255 265 }); 256 266 }); -
trunk/Source/WebKit/UIProcess/UserMediaProcessManager.h
r271154 r271471 49 49 50 50 private: 51 enum class ShouldNotify { Yes, No }; 52 void updateCaptureDevices(ShouldNotify); 51 53 void captureDevicesChanged(); 52 54
Note:
See TracChangeset
for help on using the changeset viewer.